赞
踩
最下面的黑色节点是哨兵节点
通常面试的时候都不给出头节点,有头节点会使红黑树变的更加容易
红黑树能不能给出三种颜色?就相当于是AVL树,AVL树是三种状态
RB树只要求是大致平衡的,不想AVL树是完全平衡的
下面两个图是等价的,所有路径都包含相同数目的黑色节点
每次新建节点的默认颜色都是红色
typedef enum {RED = 0,BLACK = 1}ColorType; typedef int KeyType; typedef struct rb_node { rb_node* leftchild; rb_node* parent; rb_node* rightchild; ColorType color; KeyType key; }rb_node,*RBTree; rb_node* BuyNode(); static rb_node* Nil = BuyNode();//哨兵节点 rb_node* BuyNode() { rb_node* s = (rb_node*)malloc(sizeof(rb_node)); if (nullptr == s) exit(1); memset(s, 0, sizeof(rb_node)); s->leftchild = Nil;//指向哨兵节点 s->rightchild = Nil;//指向哨兵节点 s->color = RED; return s; } rb_node* MakeRoot(KeyType kx) { rb_node* root = BuyNode(); root->color = BLACK; root->key = kx; return root; } //左单旋 void RotateLeft(rb_node*& tree, rb_node* ptr) { rb_node* newroot = ptr->rightchild; newroot->parent = ptr->parent; ptr->rightchild = newroot->leftchild;//1 if (newroot->leftchild != nullptr) { newroot->leftchild->parent = ptr;//2 } newroot->leftchild = ptr; if (ptr == tree) { tree = newroot; } else { if (ptr->parent->leftchild == ptr) { ptr->parent->leftchild = newroot; } else { ptr->parent->rightchild = newroot; } } ptr->parent = newroot;//3 } //右单旋 void RotateRight(rb_node*& tree, rb_node* ptr) { rb_node* newroot = ptr->leftchild;//1 newroot->parent = ptr->parent;//newroot的双亲更新a ptr->leftchild = newroot->rightchild;//2 ptr左孩子更新 if (newroot->rightchild != nullptr) { newroot->rightchild->parent = ptr;//newroot右孩子的双亲更新b } newroot->rightchild = ptr;//newroot右孩子更新3 if (ptr == tree)//如果我本身是根 { tree = newroot;//更新根 } else { if (ptr->parent->leftchild == ptr) { ptr->parent->leftchild = newroot; } else { ptr->parent->rightchild = newroot; } } ptr->parent = newroot;//ptr双亲更新c } void PassRBTree(rb_node*& tree, rb_node* p) { rb_node* _X = nullptr; for (; p != tree && p->parent->color == RED;)//p!=tree说明有双亲 { if (p->parent->parent->rightchild == p->parent)//p在p爷爷的右边 { _X = p->parent->parent->leftchild; if (_X->color == RED)//p爷爷的左孩子是红色,按照两个图等价交换颜色即可 { _X->color = BLACK; p->parent->color = BLACK; p->parent->parent->color = RED; p = p->parent->parent; } else//p爷爷的左孩子是黑色,只能旋转了 {//if条件满足,先右旋再左旋,不满足,就左旋 if (p->parent->leftchild == p)//p在p爷爷的右边,但是p在p双亲的左边,是一个折线 { p = p->parent; RotateRight(tree, p); } p->parent->color = BLACK;//p双亲的颜色变成黑 p->parent->parent->color = RED;//p爷爷的颜色变成红, //就形成了红黑红的形式,然后以黑作为根,将第一个红左单旋转下来 RotateLeft(tree, p->parent->parent);//左单旋 } } else//pa在p双亲的双亲的左边 { _X = p->parent->parent->rightchild; if (_X->color == RED)//p爷爷的右孩子是红色,按照两个图等价交换颜色即可 { _X->color = BLACK; p->parent->color = BLACK; p->parent->parent->color = RED; p = p->parent->parent; } else//p爷爷的左孩子是黑色,只能旋转了 {//if条件满足,先左旋再右旋,不满足,就右旋 if (p->parent->rightchild == p)//p在p爷爷的左边,但是p在p双亲的右边,是一个折线 { p = p->parent; RotateRight(tree, p); } p->parent->color = BLACK;//p双亲的颜色变成黑 p->parent->parent->color = RED;//p爷爷的颜色变成红, //就形成了红黑红的形式,然后以黑作为根,将第一个红左单旋转下来 RotateRight(tree, p->parent->parent);//右单旋 } } } tree->color = BLACK;//退出以后保证根是黑色 } bool Insert(rb_node*& tree, KeyType kx) { if (tree == nullptr) { tree = MakeRoot(kx); return true; } rb_node* pa = nullptr; rb_node* p = tree; while (p != nullptr && p->key != kx) { pa = p; p = kx < p->key ? p->leftchild : p->rightchild; } if (p != nullptr && p->key == kx)return false;//如果数据重复的话,返回false p = BuyNode(); p->key = kx; p->parent = pa; if (kx < pa->key) { pa->leftchild = p; } else { pa->rightchild = p; } PassRBTree(tree, p); return true; } int main() { int ar[] = { 16,3,7,11,9,26,18,14,15 }; AVLTree root = nullptr; for (auto& x : ar) { cout << Insert(root, x) << endl; } InOrder(root); cout << endl; return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。