红黑树C++

来源:互联网 发布:js 判断span 是否隐藏 编辑:程序博客网 时间:2024/05/16 08:56

红黑树定义:

1、每个结点要么是红的,要么是黑的

2、根结点是黑的

3、每个叶结点,即空节点是黑的

4、如果一个结点是红的,则它的两个儿子是黑的

5、对每个结点,从该结点到其子算结点的所有路径上包含相同数目的黑结点。


红黑树性质:

1、一棵有n个内结点的红黑树的高度至多为2lg(n+1)

2、RB-insert总共花费为O(lgn)时间,最多执行旋转次数为2次

3、RB-delete-fixup要花O(lgn)时间,最多做三次旋转。


这段代码有bug,贴出来希望同胞们帮忙指正 不知道到底是哪错了!调了好久了还没调出来 伤心,泪奔!大哭

谢谢了!!!


#include <iostream>using namespace std;class rbTree{private:typedef bool rbTree_color_type;const rbTree_color_type rbTree_red;const rbTree_color_type rbTree_black;//结点结构struct rbNode  {rbNode *parent;rbNode *left;rbNode *right;int data;rbTree_color_type color;    //颜色rbNode() : parent(NULL), left(NULL), right(NULL), data(-1), color(true){}};rbNode *root;rbNode *sentry; //哨兵结点,代表空结点public:rbTree() : sentry(new rbNode), rbTree_red(false), rbTree_black(true){root = sentry;}void createRbTree(){int val;while (cin >> val)rbInsert(val);}//中序遍历二叉树void traverse(){__traverse(root);}rbNode* treeMiniNum(){if (root == sentry){cout << "树为空!" << endl;return sentry;}while (root != sentry)root = root->left;return root;}int treeMiniNum1(){if (root == sentry){cout << "树为空!" << endl;return -1;}while (root != sentry)root = root->left;return root->data;}rbNode* treeMaxiNum(){if (root == sentry){cout << "树为空!" << endl;return sentry;}while (root != sentry)root = root->right;return root;}int treeMaxiNum1(){if (root == sentry){cout << "树为空!" << endl;return -1;}while (root != sentry)root = root->right;return root->data;}//查找前驱,与查找后继相对应rbNode* rbTreePreDecessor(rbNode* node){if (node->left != sentry){rbNode *tmpNode = node->left;while (tmpNode->right != sentry)tmpNode = tmpNode->right;return tmpNode;}rbNode *pNode = node->parent;while (pNode != sentry && node != pNode->right){node = pNode;pNode = pNode->parent;}return pNode;}//查找后继rbNode* rbTreeSuccessor(rbNode* node){if (node->right != sentry){rbNode *tmpNode = node->right;while (tmpNode->left != sentry)tmpNode = tmpNode->left;return tmpNode;}rbNode *pNode = node->parent;while (pNode != sentry && node != pNode->left){node = pNode;pNode = pNode->parent;}return pNode;}rbNode *rbSearch(int val){if (root == sentry)    return root;else{rbNode *node = root;while (node != sentry && val != node->data){               if (val < node->data)                  node = node->left;   else                   node = node->right;}return node;}}//红黑树插入void rbInsert(int val){return __rbInsert(root, val);}//红黑树删除rbNode* rbDelete(rbNode *&node){return __rbDelete(node);}private:void __traverse(rbNode *root){        if (root == sentry)           return;__traverse(root->left);cout << root->data << " ";__traverse(root->right);}void leftRotate(rbNode *&x){if (x == sentry || x->right == sentry)return;rbNode *y = x->right;     //设置yx->right = y->left;       //y的左孩子变为x的右孩子if (y->left != sentry)    //如果y的左孩子不为NIL,y->left->parent = x;  //则设置左孩子的根节点为xy->parent = x->parent;    //y成为x的父节点if (x->parent == sentry)  //如果x的父节点为NILroot = y;             //y设为根结点else if (x == x->parent->left)x->parent->left = y;elsex->parent->right = y;y->left = x;x->parent = y;}void rightRotate(rbNode *&y){if (y == sentry || y->left == sentry)return;rbNode *x = y->left;y->left = x->right;if (x->right != sentry)x->right->parent = y;x->parent = y->parent;if (y->parent == sentry)root = x;else if (y->parent->right == y)y->parent->right = x;elsey->parent->left = x;y->parent = x;x->right = y;}void __rbInsert(rbNode *&root, int val){rbNode *p = sentry;rbNode *node = root;rbNode *newNode = new rbNode;newNode->data = val;newNode->color = rbTree_red;newNode->left = sentry;newNode->right = sentry;newNode->parent = sentry;while (node != sentry && val != node->data){p = node;if (val < node->data)node = node->left;elsenode = node->right;}node = newNode;node->parent = p;if (p == sentry)    root = node;else{if (val < p->data)    p->left = node;    else    p->right = node;}__rbInsertFixUp(node);}//插入之后调整使其符合红黑树的性质void __rbInsertFixUp(rbNode *node){while (node->parent->color == rbTree_red){rbNode *pNode = node->parent;rbNode *ppNode = pNode->parent;//父节点是祖父结点的左孩子if (ppNode->left == pNode){rbNode *uncleNode = ppNode->right;//case1: 叔叔结点是红色的,需要改变颜色, if (uncleNode->color == rbTree_red){ppNode->color = rbTree_red;pNode->color = rbTree_black;uncleNode->color = rbTree_black;node = ppNode;}        //case2、case3:叔叔结点是黑色的else {//case2:该结点是父亲的右结点,转为case3if (node == pNode->right){node = pNode;leftRotate(node);}//case3:该结点是父亲的左结点node->parent->color = rbTree_black;node->parent->parent->color = rbTree_red;rightRotate(node->parent->parent);}}//父节点是祖父结点的又孩子else{rbNode *uncleNode = ppNode->left;//case4: 叔叔结点是红色的,需要改变颜色, if (uncleNode->color == rbTree_red){ppNode->color = rbTree_red;pNode->color = rbTree_black;uncleNode->color = rbTree_black;node = ppNode;}        //case5、case6:叔叔结点是黑色的else {//case2:该结点是父亲的右结点,转为case3if (node == pNode->left){node = pNode;rightRotate(node);}    //case3:该结点是父亲的左结点node->parent->color = rbTree_black;node->parent->parent->color = rbTree_red;leftRotate(node->parent->parent);}}}//保证父结点是黑色的root->color = rbTree_black;}rbNode* __rbDelete(rbNode* &node){rbNode *delNode = node;if (node->left != sentry | node->right != sentry)delNode = node;elsedelNode = rbTreeSuccessor(node);rbNode *delNodeChild;if (delNode->left != sentry)delNodeChild = delNode->left;elsedelNodeChild = delNode->right;delNodeChild->parent = delNode->parent;if (delNode->parent == sentry)root = delNodeChild;else if (delNode == delNode->parent->left)delNode->parent->left = delNodeChild;elsedelNode->parent->right = delNodeChild;if (delNode != node){node->data = delNode->data;node->color = delNode->color;}if (delNode->color == rbTree_black)__rbDeleteFixUp(delNode);return delNode;}void __rbDeleteFixUp(rbNode *node){while (node != root && node->color == rbTree_black){rbNode *pnode = node->parent;//结点为父结点的左孩子if (node == pnode->left){rbNode *uncleNode = pnode->right;//case1: 结点的兄弟结点为红色if (uncleNode->color == rbTree_red){uncleNode->color = rbTree_black;pnode->color = rbTree_red;leftRotate(pnode);uncleNode = uncleNode->left;}//case2、case3、case4: 结点的兄弟结点是黑色的else if (uncleNode->color == rbTree_black){//case2: 叔叔结点的左孩子、右孩子都是黑色的,进行循环if (uncleNode->left->color == rbTree_black &&uncleNode->right->color == rbTree_black){uncleNode->color = rbTree_red;node = pnode;}//case3: 叔叔结点的左孩子是红色的,右孩子是黑色的,转为case4else if (uncleNode->right->color == rbTree_black){uncleNode->color = rbTree_red;uncleNode->left->color = rbTree_black;rightRotate(uncleNode);}//case4: 叔叔结点的左孩子是黑色的,右孩子是红色的pnode->color = rbTree_black;uncleNode->color = rbTree_red;uncleNode->right->color = rbTree_black;leftRotate(pnode);}}else{rbNode *uncleNode = pnode->left;//case1: 结点的兄弟结点为红色if (uncleNode->color == rbTree_red){uncleNode->color = rbTree_black;pnode->color = rbTree_red;leftRotate(pnode);uncleNode = uncleNode->right;}//case2、case3、case4: 结点的兄弟结点是黑色的else if (uncleNode->color == rbTree_black){//case2: 叔叔结点的左孩子、右孩子都是黑色的,进行循环if (uncleNode->left->color == rbTree_black &&uncleNode->right->color == rbTree_black){uncleNode->color = rbTree_red;node = pnode;}//case3: 叔叔结点的左孩子是红色的,右孩子是黑色的,转为case4else if (uncleNode->left->color == rbTree_black){uncleNode->color = rbTree_red;uncleNode->right->color = rbTree_black;leftRotate(uncleNode);}//case4: 叔叔结点的左孩子是黑色的,右孩子是红色的pnode->color = rbTree_black;uncleNode->color = rbTree_red;uncleNode->left->color = rbTree_black;rightRotate(pnode);}}}node->color = rbTree_black;}};int main(){rbTree rbtree;rbtree.createRbTree();rbtree.traverse();cout << endl;system("pause");return 0;}


0 0
原创粉丝点击