Questa è una mia implementazione in C dell'algoritmo illustrato nel libro Introduzione agli algoritmi e strutture dati di Cormen, Leiserson, Rivest e Stein:
Devo separare il codice in due post perché è troppo lungo e non me lo fa inserire:
Parte prima:
codice:#include <stdio.h> #include <malloc.h> #define MAX_STACK 100 typedef struct tagTree { int data; char color; struct tagTree *father; struct tagTree *left; struct tagTree *right; } Tree; Tree *pNil = NULL; Tree *NewNode(int info); Tree *InsertNode(Tree *node, int key); void InsertFixup(Tree **head, Tree **z); Tree *DeleteNode(Tree *root, Tree *z); void DeleteFixup(Tree **head, Tree **x); void FreeTree(Tree *head); void InitNil(Tree **p); Tree *TreeRotateLeft(Tree *head, Tree *node); Tree *TreeRotateRight(Tree *head, Tree *node); void TreeSuccessor(Tree *current, Tree **result); void TreePredecessor(Tree *current, Tree **result); void ReverseInOrder(Tree *head); void InOrder(Tree *head); void PreOrder(Tree *head); void PostOrder(Tree *head); void SearchFirst(Tree *head, Tree **result, int key); void SearchNext(Tree *head, Tree **result, int key); void TreeMinimum(Tree *head, Tree **result); void TreeMaximum(Tree *head, Tree **result); int TreeSize(Tree *head); int TreeDepth(Tree *head); int IsTriangular(Tree *head); void InitNil(Tree **p) { *p = NewNode(0); if ( *p ) { (*p)->data = 0; (*p)->color = 'b'; (*p)->left = NULL; (*p)->right = NULL; (*p)->father = NULL; } else { printf("Errore nell'inizializzazione di pNil.\n"); } } Tree *NewNode(int info) { Tree *r; r = (Tree *) malloc(sizeof(Tree)); if( !r ) { printf("Memoria insufficiente.\n"); return pNil; } r->data = info; r->color = 'b'; /* 'b' = Black; 'r' = Red */ r->father = pNil; r->left = pNil; r->right = pNil; return r; } Tree *InsertNode(Tree *node, int key) { Tree *z = pNil; Tree *y = pNil; Tree *pRadice = pNil; z = NewNode(key); if ( z == pNil ) return pNil; pRadice = node; while ( pRadice != pNil ) { y = pRadice; if ( z->data < pRadice->data ) pRadice = pRadice->left; else pRadice = pRadice->right; } z->father = y; if ( y == pNil ) { printf("Inserisco la radice -> %d\n", key); node = z; } else { if ( z->data < y->data ) { printf("Inserisco %d a sinistra di %d\n", z->data, y->data); y->left = z; } else { printf("Inserisco %d a destra di %d\n", z->data, y->data); y->right = z; } } z->left = pNil; z->right = pNil; z->color = 'r'; /* Red */ InsertFixup(&node, &z); return node; } void InsertFixup(Tree **head, Tree **z) { Tree *y = pNil; while ( (*z)->father->color == 'r' ) { if ( (*z)->father == (*z)->father->father->left ) { y = (*z)->father->father->right; if ( y->color == 'r' ) { (*z)->father->color = 'b'; y->color = 'b'; (*z)->father->father->color = 'r'; *z = (*z)->father->father; } else { if ( *z == (*z)->father->right ) { *z = (*z)->father; *head = TreeRotateLeft(*head, *z); } (*z)->father->color = 'b'; (*z)->father->father->color = 'r'; *head = TreeRotateRight(*head, (*z)->father->father); } } else { y = (*z)->father->father->left; if ( y->color == 'r' ) { (*z)->father->color = 'b'; y->color = 'b'; (*z)->father->father->color = 'r'; *z = (*z)->father->father; } else { if ( *z == (*z)->father->left ) { *z = (*z)->father; *head = TreeRotateRight(*head, *z); } (*z)->father->color = 'b'; (*z)->father->father->color = 'r'; *head = TreeRotateLeft(*head, (*z)->father->father); } } } (*head)->color = 'b'; } Tree *DeleteNode(Tree *root, Tree *z) { Tree *y = pNil; Tree *x = pNil; if ( root == pNil || z == pNil ) return root; if ( z->left == pNil || z->right == pNil ) y = z; else TreeSuccessor(z, &y); if ( y->left != pNil ) x = y->left; else x = y->right; x->father = y->father; if ( y->father == pNil ) { root = x; } else { if ( y == y->father->left ) y->father->left = x; else y->father->right = x; } if ( y != z ) z->data = y->data; if ( y->color == 'b' ) DeleteFixup(&root, &x); free(y); return root; } void DeleteFixup(Tree **head, Tree **x) { Tree *w = pNil; while ( *x != *head && (*x)->color == 'b' ) { if ( *x == (*x)->father->left ) { w = (*x)->father->right; if ( w->color == 'r' ) { w->color = 'b'; (*x)->father->color = 'r'; *head = TreeRotateLeft(*head, (*x)->father); w = (*x)->father->right; } if ( w->left->color == 'b' && w->right->color == 'b' ) { w->color = 'r'; (*x) = (*x)->father; } else { if ( w->right->color == 'b' ) { w->left->color = 'b'; w->color = 'r'; *head = TreeRotateRight(*head, w); w = (*x)->father->right; } w->color = (*x)->father->color; (*x)->father->color = 'b'; w->right->color = 'b'; *head = TreeRotateLeft(*head, (*x)->father); *x = *head; } } else { w = (*x)->father->left; if ( w->color == 'r' ) { w->color = 'b'; (*x)->father->color = 'r'; *head = TreeRotateRight(*head, (*x)->father); w = (*x)->father->left; } if ( w->right->color == 'b' && w->left->color == 'b' ) { w->color = 'r'; (*x) = (*x)->father; } else { if ( w->left->color == 'b' ) { w->right->color = 'b'; w->color = 'r'; *head = TreeRotateLeft(*head, w); w = (*x)->father->left; } w->color = (*x)->father->color; (*x)->father->color = 'b'; w->left->color = 'b'; *head = TreeRotateRight(*head, (*x)->father); *x = *head; } } } (*x)->color = 'b'; } void FreeTree(Tree *head) { Tree *temp1, *temp2; Tree *stack[MAX_STACK]; int top; top = 0; if ( head == pNil ) return; temp1 = temp2 = head; while ( temp1 != pNil ) { for(; temp1->left != pNil; temp1 = temp1->left) stack[top++] = temp1; while ( (temp1 != pNil) && (temp1->right == pNil || temp1->right == temp2) ) { temp2 = temp1; free(temp2); if ( top == 0 ) return; temp1 = stack[--top]; } stack[top++] = temp1; temp1 = temp1->right; } } Tree *TreeRotateLeft(Tree *head, Tree *node) { Tree *y; if ( head == pNil || node == pNil ) return head; if ( node->right == pNil ) return head; y = node->right; node->right = y->left; if ( y->left != pNil ) { y->left->father = node; } y->father = node->father; if ( node->father == pNil ) { head = y; } else { if ( node == node->father->left ) { node->father->left = y; } else { node->father->right = y; } } y->left = node; node->father = y; return head; } Tree *TreeRotateRight(Tree *head, Tree *node) { Tree *y; if ( head == pNil || node == pNil ) return head; if ( node->left == pNil ) return head; y = node->left; node->left = y->right; if ( y->right != pNil ) { y->right->father = node; } y->father = node->father; if ( node->father == pNil ) { head = y; } else { if ( node == node->father->right ) { node->father->right = y; } else { node->father->left = y; } } y->right = node; node->father = y; return head; }

Rispondi quotando