紅黑樹的插入,刪除幾種狀況,算法導論,已經寫得很詳細了,下面給出具體的實現代碼,包含,插入,查找,刪除。修改比較簡單,查找到該點,給key從新賦值,便可。ios
#ifndef RB_TREE_H #define RB_TREE_H #include<vector> const int BLACK = -1; const int RED = 1; static int number1 = 0; static int number2 = 0; static int number3 = 0; static int number4 = 0; static int number5 = 0; static int number6 = 0; struct RB_TREE_NODE{ public: RB_TREE_NODE(int a) { key = a; color = BLACK; p =0; left = 0; right = 0; } ~RB_TREE_NODE() { } int key; int color; RB_TREE_NODE* p; RB_TREE_NODE* left; RB_TREE_NODE* right; }; static RB_TREE_NODE NIL = { 0 }; #define PNIL (&NIL) struct RB_TREE { RB_TREE() { root->left = PNIL; root->right = PNIL; root->p = PNIL; } RB_TREE_NODE* root=PNIL; ////插入節點z void RB_TREE_INSERT(RB_TREE* root, RB_TREE_NODE* z); ///插入節點z後對該樹進行調整,使之從新知足紅黑樹的條件 void RB_TREE_INSERT_FIXUP(RB_TREE*root, RB_TREE_NODE* z); ////刪除節點z void RB_TREE_DELETE(RB_TREE* root, RB_TREE_NODE* z); ///刪除節點z後對該樹進行調整,使該樹從新知足紅黑樹的條件 void RB_TREE_DELETE_FIXUP(RB_TREE* root, RB_TREE_NODE*z); ///x的前驅,不然返回nullptr RB_TREE_NODE* RB_TREE_PREDECESSOR(RB_TREE* root, RB_TREE_NODE* x); ///x的後驅,不然返回nullptr RB_TREE_NODE* RB_TREE_SUCCESSOR(RB_TREE* root, RB_TREE_NODE* x); ///以x爲根的樹中最小值 RB_TREE_NODE* RB_TREE_MINMUM(RB_TREE_NODE* x); ///以x爲根的樹中的最大值 RB_TREE_NODE* RB_TREE_MAXMUM(RB_TREE_NODE* x); ///對x節點進行左旋轉 void RB_LEFT_ROTATE(RB_TREE* root, RB_TREE_NODE* x); ///對x節點進行右旋轉 void RB_RIGHT_ROTATE(RB_TREE*root, RB_TREE_NODE* x); ///用以節點v爲根的樹替換以節點u爲根的樹 void RB_TRANSPLANT(RB_TREE* root, RB_TREE_NODE* u, RB_TREE_NODE*v); ///搜索節點值爲value的節點,並返回,搜索不到返回PNIL RB_TREE_NODE* RB_SEARCH(RB_TREE* root, int value); ////搜索全部節點值爲value的節點並返回 std::vector<RB_TREE_NODE*> RB_SEARCH_ALL(RB_TREE* root, int value); }; void RB_TREE::RB_TREE_INSERT(RB_TREE* root, RB_TREE_NODE* z) { z->left = PNIL; ////哨兵並不是空節點,new 出的RB_TREE_NODE的左右孩子爲空節點不是哨兵,因此插入前,先將左右孩子置爲哨兵 z->right = PNIL; RB_TREE_NODE* x = RB_TREE::root; RB_TREE_NODE* y=PNIL; while (x != PNIL) { y = x; if (z->key < x->key) x = x->left; else x = x->right; } z->p = y; if (y == PNIL)root->root = z; else if (z->key < y->key)y->left = z; else y->right = z; z->color = RED; RB_TREE_INSERT_FIXUP(root, z); } void RB_TREE::RB_TREE_INSERT_FIXUP(RB_TREE* root, RB_TREE_NODE*z) { while (z->p->color == RED&&z->p != PNIL) { if (z->p->p->left == z->p) { RB_TREE_NODE* y = z->p->p->right; if (y->color == RED) { number1++; z->p->color = BLACK; y->color = BLACK; z->p->p->color = RED; z = z->p->p; } else { number2++; if (z == z->p->right) { number3++; z = z->p; RB_LEFT_ROTATE(root, z); } z->p->color = BLACK; z->p->p->color = RED; RB_RIGHT_ROTATE(root, z->p->p); } } else { RB_TREE_NODE* y = z->p->p->left; if (y->color == RED) { number4++; z->p->color = BLACK; y->color = BLACK; z->p->p->color = RED; z = z->p->p; } else { number5++; if (z == z->p->left) { number6++; z = z->p; RB_RIGHT_ROTATE(root, z); } z->p->color = BLACK; z->p->p->color = RED; RB_LEFT_ROTATE(root, z->p->p); } } } root->root->color = BLACK; } void RB_TREE::RB_LEFT_ROTATE(RB_TREE* root, RB_TREE_NODE* x) { RB_TREE_NODE* y = x->right; x->right = y->left; if (y->left!=PNIL) y->left->p = x; y->p = x->p; if (x->p == PNIL)root->root = y; else if (x->p->left ==x)x->p->left = y; else x->p->right = y; x->p = y; y->left = x; } void RB_TREE::RB_RIGHT_ROTATE(RB_TREE*root, RB_TREE_NODE* x) { RB_TREE_NODE* y = x->left; x->left = y->right; if (y->right != PNIL) y->right->p = x; y->p = x->p; if (x->p == PNIL)root->root = y; else if (x->p->left == x) x->p->left = y; else x->p->right = y; x->p = y; y->right = x; } RB_TREE_NODE* RB_TREE::RB_TREE_PREDECESSOR(RB_TREE* root, RB_TREE_NODE* x) { if (x == RB_TREE_MINMUM(root->root))return x; if (x->left != PNIL)return RB_TREE_MAXMUM(x->left); RB_TREE_NODE* y = x->p; while (y != PNIL&&x == y->left) { x = y; y = y->p; } return y; } RB_TREE_NODE* RB_TREE::RB_TREE_SUCCESSOR(RB_TREE* root, RB_TREE_NODE* x) { if (x == RB_TREE_MAXMUM(root->root))return x; if (x->right != PNIL)return RB_TREE_MINMUM(x->right); RB_TREE_NODE* y = x->p; while (y != PNIL&&x == y->right) { x = y; y = y->p; } return y; } RB_TREE_NODE* RB_TREE::RB_TREE_MINMUM(RB_TREE_NODE* x) { while (x->left != PNIL) x = x->left; return x; } RB_TREE_NODE* RB_TREE::RB_TREE_MAXMUM(RB_TREE_NODE* x) { while (x->right != PNIL) x = x->right; return x; } void RB_TREE::RB_TRANSPLANT(RB_TREE* root, RB_TREE_NODE* u, RB_TREE_NODE* v) { if (u->p == PNIL)root->root = v; else if (u == u->p->left)u->p->left=v; else u->p->right = v; if (v!=PNIL) v->p = u->p; } RB_TREE_NODE* RB_TREE::RB_SEARCH(RB_TREE* root, int value) { // 此爲刪除第一個值爲value的節點 RB_TREE_NODE* temp = root->root; while (temp != PNIL&&temp->key != value) { if (value < temp->key) { temp = temp->left; } else { temp = temp->right; } } return temp; } std::vector<RB_TREE_NODE*> RB_TREE::RB_SEARCH_ALL(RB_TREE* root, int value) { std::vector<RB_TREE_NODE*>result; RB_TREE_NODE* temp = root->root; while (temp != PNIL&&temp->key != value) { if (value < temp->key) { temp = temp->left; } else { temp = temp->right; } } result.push_back(temp); RB_TREE_NODE* temp2 = temp; while(temp != PNIL) /////尋找temp的前驅值相等的 { RB_TREE_NODE* t1 = RB_TREE_PREDECESSOR(root, temp); if (t1!=PNIL&&t1->key == temp->key) result.push_back(t1); else break; temp = t1; } temp = temp2; while (temp!=PNIL) ////尋找temp的後驅值相等的 { RB_TREE_NODE* t1 = RB_TREE_SUCCESSOR(root, temp); if (t1!=PNIL&&t1->key==temp->key) result.push_back(t1); else break; temp = t1; } return result; } void RB_TREE::RB_TREE_DELETE(RB_TREE* root, RB_TREE_NODE* z) { RB_TREE_NODE* y = z; RB_TREE_NODE* x; int origin_color = y->color; if (z->left == PNIL) { x = z->right; RB_TRANSPLANT(root, z, z->right); } else if (z->right == PNIL) { x = z->left; RB_TRANSPLANT(root, z, z->left); } else { y = RB_TREE_MINMUM(z->right); origin_color = y->color; x = y->right; if (y->p == z) { x->p = y; ////防止y的子節點都是哨兵,進行刪除調整時,須要找到x的父節點,而哨兵沒有父節點。 } else { RB_TRANSPLANT(root, y, y->right); y->right = z->right; y->right->p = y; } RB_TRANSPLANT(root, z, y); y->left = z->left; y->left->p = y; y->color = z->color; z->p = nullptr; ///////刪除節點z時,對父節點,子節點指針置爲空,只刪除節點z的區域 z->right = nullptr; z->left = nullptr; delete z; } if (origin_color == BLACK) { RB_TREE_DELETE_FIXUP(root, x); } } void RB_TREE:: RB_TREE_DELETE_FIXUP(RB_TREE* root, RB_TREE_NODE*z) { while (z != root->root&&z->color == BLACK) { if (z == z->p->left) { RB_TREE_NODE* y = z->p->right; if (y->color == RED) /////case1 { y->color = BLACK; z->p->color = RED; RB_LEFT_ROTATE(root, z->p); y = z->p->right; ////轉到case2,3,4中的一種 } if (y->left->color == BLACK&&y->right->color == BLACK) { y->color = RED; ////case2 z = z->p; } else { if (y->right->color == BLACK) { y->left->color = BLACK; y->color = RED; RB_RIGHT_ROTATE(root, y); ////case3 轉到case4 y = z->p->right; } y->color = z->p->color; z->p->color = BLACK; ////case4; y->right->color = BLACK; RB_LEFT_ROTATE(root, z->p); z = root->root; } } else ////與以上left和right互換 { RB_TREE_NODE* y = z->p->left; if (y->color == RED) { y->color = BLACK; z->p->color = RED; RB_RIGHT_ROTATE(root, z->p); y = z->p->left; } if (y->right->color == BLACK&&y->left->color == BLACK) { y->color = RED; z = z->p; } else { if (y->left->color == BLACK) { y->right->color = BLACK; y->color = RED; RB_LEFT_ROTATE(root, y); y = z->p->left; } y->color = z->p->color; z->p->color = BLACK; y->left->color = BLACK; RB_RIGHT_ROTATE(root, z->p); z = root->root; } } } z->color = BLACK; } #endif
測試主函數算法
#include"RB_TREE1.h" #include<iostream> using namespace std; void print(RB_TREE* root) /////從小到大輸出全部的樹節點值 { RB_TREE_NODE* pmin = root->RB_TREE_MINMUM(root->root); RB_TREE_NODE* pmax = root->RB_TREE_MAXMUM(root->root); int i = 0; while (true) { if (i++ % 10 == 0)cout << endl; cout << pmin->key << " "; if (pmin == pmax)break; pmin = root->RB_TREE_SUCCESSOR(root, pmin); } cout <<endl<< endl << "++++++++++++++++++++++++++++++++++++++" << endl; } int main() { int a[1000]; for (int i = 0; i < 1000; i++) { a[i] = rand() % 100; } RB_TREE* root = new RB_TREE(); for (int i = 0; i < 100; i++) { RB_TREE_NODE* z = new RB_TREE_NODE(a[i]); root->RB_TREE_INSERT(root,z); } cout << "++++++++++++++++++++++++++++++++++++++" << endl; RB_TREE_NODE* pmin = root->RB_TREE_MINMUM(root->root); RB_TREE_NODE* pmax = root->RB_TREE_MAXMUM(root->root); print(root); cout << endl << endl << "++++++++++++++++++++++++++++++++" << endl; vector<RB_TREE_NODE*>result1 = root->RB_SEARCH_ALL(root, 50); for (RB_TREE_NODE* temp : result1) { cout << temp->key << " "; } vector<RB_TREE_NODE*>result2 = root->RB_SEARCH_ALL(root, 29); for (RB_TREE_NODE* temp : result2) { cout << temp->key << " "; } vector<RB_TREE_NODE*>result3 = root->RB_SEARCH_ALL(root, 82); for (RB_TREE_NODE* temp : result3) { cout << temp->key << " "; } cout << endl << "++++++++++++++++++++++++++++++++++++++" << endl; for (RB_TREE_NODE* temp : result1) { if (temp != PNIL)root->RB_TREE_DELETE(root,temp); } print(root); for (RB_TREE_NODE* temp : result2) { if (temp != PNIL)root->RB_TREE_DELETE(root, temp); } print(root); for (RB_TREE_NODE* temp : result3) { if (temp != PNIL)root->RB_TREE_DELETE(root, temp); } print(root); /////對應插入的case狀況 cout << endl << number1 << " " << number2 << " " << number3 << " " << number4 << " " << number5 << " " << number6 << endl; cout << endl << "====================" << endl; cout << root->root->key << " " << root->root->color << endl; cout << root->root->left->key << " " << root->root->left->color << endl; cout << root->root->right->key << " " << root->root->right->color << endl; cout << root->root->left->left->key << " " << root->root->left->left->color << endl; cout << root->root->left->right->key << " " << root->root->left->right->color << endl; cout << root->root->right->left->key << " " << root->root->right->left->color << endl; cout << root->root->right->right->key << " " << root->root->right->right->color << endl; }
手動測試劃出11個元素的紅黑樹,與筆畫出的結果一致。函數