通俗易懂看RB-tree(二)
阿新 • • 發佈:2019-02-05
RB-tree結點設計
codes:
typedef bool rb_tree_color_type const rb_tree_color_type rb_tree_red=false; const rb_tree_color_type rb_tree_black=true; struct rb_tree_node_base { typedef rb_tree_color_type color_type;//顏色種類 typedef rb_tree_node_base *base_ptr;//紅黑樹節點指標 color_type color; base_ptr parent; base_ptr left; base_ptr right; };
迭代器設計
codes:void increment//前進,含義是找到比當前結點大的元素中最小的元素 { if(node->right!=0) { node=node->right; while(node->left!=0) node=node->left; } else { base_ptr y=node->parent; while(node==y->right)//若此時是y的右節點,則一直向上遞迴 { node=y; y=y->parent; } /*此時node為y的左節點,而node的右節點和y都大於node 所以當node的右節點不等於y 時,返回y;(若相等,出錯)*/ if(node->right!=y) node=y; } } void decrement//後退,含義是找比當前元素小的元素中最大的元素 { if(node->color==rb_tree_red&&node->parent->parent==node) node=node->right;//此處node是根節點 else if(node->left!=0) { base_ptr y=node->left; while(y->right!=0) y=y->right; node=y; } else { //若沒有左節點,則判斷該節點是否是左節點,向上遞迴,直到該節點為右節點停止; //由二叉搜尋樹的性質,節點只要在右子樹上,就肯定比父節點大,所以尋找以該節點為右子樹的父節點; base_ptr y=node->parent; while(node==y->left) { node=y; y=y->parent; } node=y; } }
調整RB-tree(旋轉及改變顏色)
inline void rb_tree_rebalance(rb_tree_node_base*x,rb_tree_node_base *&root) { x->color=rb_tree_red;//新節點必為紅色; while(x!=root&&x->parent->color==rb_tree_red) { if(x->parent==x->parent->parent->left) { rb_tree_node_base *y=x->parent->parent->right;//令y為伯父節點; if(y&&y->color==rb_tree_red) { x->parent->color=rb_tree_black; y->color=rb_tree_black; x->parent->parent->color=rb_tree_red; x=x->parent->parent; } else { //無伯父節點,或伯父節點為黑; if(x==x->parent->right)//此時是內側插入 { x=x->parent; rb_tree_rotate_left(x,root); } x->parent->color=rb_tree_black; x->parent->parent=rb_tree_red; rb_tree-rotate_right(x->parent->parent,root); } else//父節點為祖父節點之右節點; { rb_tree_node_base *y=x->parent->parent->left; if(y&&y->color==rb_tree_red) { x->parent->color=rb_tree_black; y->color=rb_tree_black; x->parent->parent=rb_tree_red; x=x->parent->parent; } else//無伯父節點,或者伯父節點為黑 { if(x==x->parent->left) { x=x->parent; rb_tree_rotate_right(x,root); } x->parent->color=rb_tree_black; x->parent->parent->color=rb_tree_red; rb_tree_rotate_left(x->parent->parent,root); } } } } root->color=rb_tree_black;//根節點永遠為黑色; } //左旋轉 inline void rb_tree_rotate_left(rb_tree_node_base *x,rb_tree_node_base *&root) { //x為旋轉點; rb_tree_node_base *y=x->right;//y為旋轉點的右子結點 x->right=y->left; if(y->left!=0) y->left->parent=x; y->parent=x->parent; //y要完全代替x的地位,將x的所有關係完全接收過來; if(x==root) rooy=y; else if(x==x->parent->left) x->parent->left=y; else x->parent->right=y; y->left=x; x->parent=y; } //右旋轉 inline void rb_tree_rotate_right(rb_tree_node_base *x,rb_tree_node_base *&root) { rb_tree_node_base *y=x->left; x->left=y->right; if(y->right!=0) y->right->paren=x; y->parent=x->parent; if(x==root) root=y; else if(x=x->parent->left) x->parent->left=y; else x->parent->right=y; y->right=x; x->parent=y; }