红黑树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
- 红黑树(C#)
- 红黑树与C实现算法 - RedBlackTree.c
- 红黑树C实现
- 红黑树<C语言实现>
- C语言红黑树
- 红黑树C语言实现
- 红黑树-C语言实现
- 红黑树的C实现
- 红黑树(c实现)
- C语言实现红黑树
- C++---STL-红黑树
- 【c++/数据结构】红黑树-RBTree
- c
- c
- c
- c
- C
- c
- IIS上部署MVC 4.0网站的问题
- Qtimer类详解 .
- Android多点触摸与手势
- Java自学--Date类 格式化输出时间
- NGUI 按钮音效问题
- 红黑树C++
- SVN中trunk,branches,tags用法详解
- 面试10大算法汇总+常见题目解答
- Oracle学习.数据文件、控制文件、重做日志文件的理解
- hdu1498 二分图匹配(多次最小点覆盖)
- iOS 内存管理
- windows8下安装SSDB1.6.6
- VC通过WinExec和ShellExecute打开指定程序或者文件的方法
- 为Eclipse安装Tomcat插件,不出现Tomcat图标