Node* fixAVL(Node* node) { if (node != NULL) { node -> factor = getFactor(node); if(node -> factor == 2) { node -> left -> factor = getFactor(node -> left); if(node -> left -> factor > 0) { node = rotationRight(node); } else { node = rotationRight_Right(node); } } else if(node -> factor == -2) { node -> right -> factor = getFactor(node -> right); if(node -> right -> factor < 0) { node = rotationLeft(node); } else { node = rotationLeft_Left(node); } } node -> left = fixAVL(node -> left); node -> right = fixAVL(node -> right); } return node; }
// usuwa wezel z zadanymi danymi bool DrzewoCzerCzar::remove(int data) { Node* X = find(data); if (X != NULL) { Node * W, *Y, *Z; if ((X->left == guard) || (X->right == guard)) Y = X; else Y = poprzednik(X); if (Y->left != guard) Z = Y->left; else Z = Y->right; Z->up = Y->up; if (Y->up == guard) root = Z; else if (Y == Y->up->left) Y->up->left = Z; else Y->up->right = Z; if (Y != X) X->data = Y->data; // przywracanie struktury drzewa czerwono-czarnego if (Y->color == 'b') while ((Z != root) && (Z->color == 'b')) { //opoznienie do pomiarow for (int i = 0; i < 2000; i++); if (Z == Z->up->left) { W = Z->up->right; if (W->color == 'r') { W->color = 'b'; Z->up->color = 'r'; rotationLeft(Z->up); W = Z->up->right; } if ((W->left->color == 'b') && (W->right->color == 'b')) { W->color = 'r'; Z = Z->up; continue; } if (W->right->color == 'b') { W->left->color = 'b'; W->color = 'r'; rotationRight(W); W = Z->up->right; } W->color = Z->up->color; Z->up->color = 'b'; W->right->color = 'b'; rotationLeft(Z->up); Z = root; } else { W = Z->up->left; if (W->color == 'r') { W->color = 'b'; Z->up->color = 'r'; rotationRight(Z->up); W = Z->up->left; } if ((W->left->color == 'b') && (W->right->color == 'b')) { W->color = 'r'; Z = Z->up; continue; } if (W->left->color == 'b') { W->right->color = 'b'; W->color = 'r'; rotationLeft(W); W = Z->up->left; } W->color = Z->up->color; Z->up->color = 'b'; W->left->color = 'b'; rotationRight(Z->up); Z = root; } } Z->color = 'b'; delete Y; return true; } return false; }
// wstawianie elementu do drzewa czerwono-czarnego void DrzewoCzerCzar::insert(int data) { Node* tempRoot = guard; Node* temp = root; // wstawianie elementu jak do BST while (temp != guard) { //opoznienie do pomiarow for (int i = 0; i<1000; i++); tempRoot = temp; if (data > temp->data) temp = temp->right; else temp = temp->left; } if (tempRoot == guard) { root = new Node(); root->up = guard; root->left = guard; root->right = guard; root->data = data; root->color = 'b'; return; } else { if (data > tempRoot->data) { tempRoot->right = new Node(); temp = tempRoot->right; } else { tempRoot->left = new Node(); temp = tempRoot->left; } temp->left = guard; temp->right = guard; temp->up = tempRoot; temp->data = data; temp->color = 'r'; } // przywracanie warunkow drzewa czerwono-czarnego while (true) { //opoznienie do pomiarow for (int i = 0; i<1000; i++); if (temp->up->color == 'b') return; else { // ustalenie wujka Node* wujek = NULL; char stronaPokr; // l - lewy syn, p - prawy syn int przypadek = -1; // 0 - domyslnie, 1 - przypadek lustrzany if (temp->up->up->left->left == temp) { stronaPokr = 'l'; wujek = temp->up->up->right; przypadek = 0; } else if (temp->up->up->left->right == temp) { stronaPokr = 'p'; wujek = temp->up->up->right; przypadek = 0; } else if (temp->up->up->right->left == temp) { stronaPokr = 'l'; wujek = temp->up->up->left; przypadek = 1; } else if (temp->up->up->right->right == temp) { stronaPokr = 'p'; wujek = temp->up->up->left; przypadek = 1; } else return; // Przypadek I: wujek czerwony if (wujek->color == 'r') { temp->up->color = 'b'; // kolor ojca wujek->color = 'b'; // kolor wujka temp->up->up->color = 'r'; // kolor dziadka if (temp->up->up == root) { temp->up->up->color = 'b'; return; } else { temp = temp->up->up; continue; } } // Przypadek II: wujek czarny, a temp jest prawym dzieckiem (lub lustro) else if (wujek->color == 'b' && stronaPokr == 'p' && przypadek == 0) { temp = temp->up; rotationLeft(temp); continue; } else if (wujek->color == 'b' && stronaPokr == 'l' && przypadek == 1) { temp = temp->up; rotationRight(temp); continue; } // Przypadek III: wujek jest czarny, a temp jest lewym dzieckiem (lub lustro) else if (wujek->color == 'b' && stronaPokr == 'l' && przypadek == 0) { if (temp->up->up != guard) { if (temp->up->up->color == 'r') temp->up->up->color = 'b'; else temp->up->up->color = 'r'; } if (temp->up != guard) { if (temp->up->color == 'r') temp->up->color = 'b'; else temp->up->color = 'r'; } rotationRight(temp->up->up); return; } else if (wujek->color == 'b' && stronaPokr == 'p' && przypadek == 1) { if (temp->up->up != guard) { if (temp->up->up->color == 'r') temp->up->up->color = 'b'; else temp->up->up->color = 'r'; } if (temp->up != guard) { if (temp->up->color == 'r') temp->up->color = 'b'; else temp->up->color = 'r'; } rotationLeft(temp->up->up); return; } } } }