红黑树的C++代码实现
2016-04-24 08:24
495 查看
//这是我参考july思想写的红黑树,仅供参考,有不正确的可以指出来,一起讨论
#include <iostream> #include <string> using namespace std; #define BLACK 0 #define RED 1 template <class T> class my_rbtree;//前置声明 /* 类名:my_rbnode(红黑树节点) */ template <class T> class my_rbnode { friend class my_rbtree<T>;//友元 public: my_rbnode(T _data) { data = _data; colour = RED;//默认为红色 left = NULL; right = NULL; parent = NULL; } private: T data;//元素值 int colour;//颜色 my_rbnode<T>* left;//左孩子 my_rbnode<T>* right;//右孩子 my_rbnode<T>* parent;//父节点 }; /* 类名:my_rbtree */ template <class T> class my_rbtree { public: my_rbtree() { root = NULL; } /*函数名:rb_left_rotate 函数作用:左旋 参数:my_rbnode<T> *node(旋转的节点) 返回值:无 */ void rb_left_rotate(my_rbnode<T> *node) { my_rbnode<T>* node_right = node->right; //断开node->node_right的指针,并把node_right->left的孩子赋值给node //赋值前判断node_right->left是否为空 node->right = node_right->left; if ( node->right != NULL) { node_right->left->parent = node; } //断开node_right->node的指针并把node->parent赋值给 node_right的父指针 node_right->parent = node->parent; if (node_right->parent != NULL) { //判断node是node->parent的左孩子还是右孩子来确定node_right的位置 if (node == node_right->parent->left) { node->parent->left = node_right; } else { node->parent->right = node_right; } } else//如果node的父指针为空说明node为root,现在node_right为node的父指针,则root为node_right { root = node_right; } node_right->left = node; node->parent = node_right; } /*函数名:rb_right_rotate 函数作用:右旋 参数:my_rbnode<T> *node(旋转的节点) 返回值:无 */ void rb_right_rotate(my_rbnode<T> *node) { my_rbnode<T>* node_left = node->left; node->left = node_left->right; if (node->left != NULL) { node_left->right->parent = node; } node_left->left = node; node_left->parent = node->parent; if (node_left->parent != NULL) { if (node == node->parent->left) { node->parent->left = node_left; } else { node->parent->right = node_left; } } else { root = node_left; } node->parent = node_left; } /*函数名:rbtree_insert_rebalance 函数作用:插入的修复 参数:my_rbnode<T>* node(插入的节点) 返回值:无 */ void rbtree_insert_rebalance(my_rbnode<T>* node) { my_rbnode<T>* node_parent = NULL; my_rbnode<T>* node_grandparent = NULL; my_rbnode<T>* node_uncle = NULL; my_rbnode<T>* tmp = NULL;//tmp为临时变量 node_parent = node->parent; while (node_parent != NULL &&node_parent->colour == RED) { node_grandparent = node_parent->parent; if (node_parent == node_grandparent->left) { node_uncle = node_grandparent->right; if (node_uncle != NULL && node_uncle->colour == RED) { node_parent->colour = BLACK; node_uncle->colour = BLACK; node_grandparent->colour = RED; node = node_grandparent;//转移不平衡点 node_parent = node->parent; } else { /*情况2 叔叔节点为黑色 且 当前节点的父节点为右孩子*/ if (node == node_parent->right) { rb_left_rotate(node_parent); tmp = node_parent; node_parent = node; node = tmp; } //情况3 当前节点的父节点为红色,叔叔节点为黑色,当前节点是父节点的左孩子 rb_right_rotate(node_grandparen c76e t); node_parent->colour = BLACK; node_grandparent->colour = RED; } } else//树的对称性下面是上面的对称过去的情况 { node_uncle = node_grandparent->left; if (node_uncle != NULL && node_uncle->colour == RED) { node_parent->colour = BLACK; node_uncle->colour = BLACK; node_grandparent->colour = RED; node = node_grandparent;//转移不平衡点 node_parent = node->parent; } else { if (node == node_parent->left) { rb_right_rotate(node_parent); tmp = node_parent; node_parent = node; node = tmp; } node_parent->colour = BLACK; node_grandparent->colour = RED; rb_left_rotate(node_grandparent); } } } root->colour = BLACK; } /* 函数名:rbtree_insert 作用:插入元素 参数:T _data(元素值) 返回值:无 */ void rbtree_insert(T _data) { my_rbnode<T>* newnode = new my_rbnode<T>(_data); if (root == NULL) { root = newnode; root->colour = BLACK; } else { my_rbnode<T>* curr = root; my_rbnode<T>* tmp = NULL; while (curr != NULL) { tmp = curr; if (curr->data > _data) { curr = curr->left; } else { curr = curr->right; } } newnode->parent = tmp; if (tmp->data > _data) { tmp->left = newnode; } else { tmp->right = newnode; } rbtree_insert_rebalance(newnode); } } /*函数名:input_tree 函数作用:把数组中的元素都插入到rbtree中 参数:T a[](数组),int length(数组长度) 返回值:无 */ void input_tree(T a[],int length) { int i; for (i = 0; i < length; i++) { rbtree_insert(a[i]); } } /* 函数名:rbtree_find 函数作用:查找 参数:T _data(查找的元素值) 返回值:my_rbnode<T>*(返回一个指查找的元素的指针) */ my_rbnode<T>* rbtree_find(T _data) { my_rbnode<T>* curr = root; while (curr != NULL) { if (curr->data > _data) { curr = curr->left; } else if (curr->data < _data) { curr = curr->right; } else { return curr; } } return NULL; } /* 函数名:rbtree_delete 函数作用:删除 参数:T _data(删除的元素值) 返回值:无*/ void rbtree_delete(T _data) { /*判断要删除的节点是否存在*/ my_rbnode<T>* node = rbtree_find(_data); if (node == NULL) { return; } my_rbnode<T>* replace = node;//后继点 my_rbnode<T>* node_child = NULL; my_rbnode<T>* node_parent =NULL; int node_colour = RED; //第一种没有孩子和只有一个孩子的情况 if (node->left == NULL || node->right == NULL) { if (node->left != NULL) { node_child = node->left; } else { node_child = node->right; } node_parent = node->parent; node_colour = node->colour; if (node_child != NULL) { node_child->parent = node_parent; } //判断父节点是否为空 if (node_parent != NULL) { //判断node为node_parent的那边孩子 if (node == node_parent->left) { node_parent->left = node_child; } else { node_parent->right = node_child; } } else { root = node_child;//父节点为空则为root } } else { //当有删除点两个孩子时得寻找一个后继点得比删除点的左孩子大而比右孩子小 //所以得从删除点的右孩子中找一个最小的点来做后继点 replace = node->right; while (replace->left != NULL) { replace = replace->left;//找后继点 } node_child = replace->right; node_parent = replace->parent; node_colour = replace->colour; //判断后继点的孩子是否为空 if (node_child != NULL) { node_child->parent = node_parent; } //判断后继点的父节点是否为空 if (node_parent != NULL) { if (node_parent->left == replace) { node_parent->left = node_child; } else { node_parent->right = node_child; } } else { root = node_child; } replace->parent = node->parent; replace->colour = node->colour; replace->left = node->left; replace->right = node->right; if (node->parent != NULL) { if (node->parent->left == node) { node->parent->left = replace; } else { node->parent->right = replace; } } else { root = replace; } node->left->parent = replace; //当node的右孩子没有右孩子时 node的右孩子为后继点则node->right == NULL if (node->right != NULL) { node->right->parent = replace; } //当node的右孩子没有左孩子时,当node被删除了 node_parent也会变成NULL if (node_parent == node) { node_parent = replace; } } delete node; if (node_colour == BLACK) { rbtree_delete_rebalance(node_child,node_parent); } } /* 函数名:rbtree_delete_rebalance 函数作用:删除修复 参数:my_rbnode<T>* node(后继点的右孩子),my_rbnode<T>* node_parent(后继点的右孩子的父节点) 返回值:无*/ void rbtree_delete_rebalance(my_rbnode<T>* node,my_rbnode<T>* node_parent) { my_rbnode<T>* brother = NULL; my_rbnode<T>* bro_left = NULL; my_rbnode<T>* bro_right = NULL; while ((!node || node->colour == BLACK) && node != root) { //判断当前节点在父节点的位置 if (node_parent->left == node) { //兄弟节点 brother = node_parent->right; //首先判断兄弟节点是否为红,如果为红直接涂黑并把父节点涂红后左旋转 //第一种情况 if (brother->colour == RED) { brother->colour = BLACK; node_parent->colour = RED; rb_left_rotate(node_parent); //旋转后重新获取兄弟节点的位置 brother = node_parent->right; } //判断兄弟节点的孩子是否全黑 //第二种情况 if ((!brother->left || brother->left->colour == BLACK) && (!brother->right || brother->right->colour == BLACK)) { brother->colour = RED; //重新获取当前节点 node = node_parent; node_parent = node->parent; } else { //第三种情况 //兄弟节点的左孩子为红右孩子为黑 if (!brother->right || brother->right->colour == BLACK) { bro_left = brother->left; if (bro_left != NULL) { bro_left->colour = BLACK; } brother->colour = RED; rb_right_rotate(brother); brother = node_parent->right; } //第四种情况 //兄弟节点右孩子为红,左孩子颜色随意 brother->colour = node_parent->colour; node_parent->colour = BLACK; if (brother->right != NULL) { brother->right->colour = BLACK; } rb_left_rotate(node_parent); node = root; break; } } else//是上面的对称情况 { brother = node_parent->left; if (brother->colour == RED) { brother->colour = BLACK; node_parent->colour = RED; rb_right_rotate(node_parent); brother = node_parent->left; } if ((!brother->left || brother->left->colour == BLACK) && (!brother->right || brother->right->colour == BLACK)) { brother->colour = RED; node = node_parent; node_parent = node->parent; } else { if (!brother->left || brother->left->colour == BLACK) { bro_right = brother->right; if (bro_right != NULL) { bro_right->colour = BLACK; } brother->colour = RED; rb_left_rotate(brother); brother = node_parent->left; } brother->colour = node_parent->colour; node_parent->colour = BLACK; if (brother->left != NULL) { brother->left->colour = BLACK; } rb_left_rotate(node_parent); node = root; break; } } } if (node != NULL) { node->colour = BLACK; } } /* 函数名:pretree 函数作用:前序遍历 参数:my_rbnode<T>* node(根节点) 返回值:无*/ void pretree(my_rbnode<T>* node) { if (node != NULL) { cout<<node->data<<'\t'; if (node->colour == BLACK) { cout<<"黑色"<<endl; } else { cout<<"红色"<<endl; } pretree(node->left); pretree(node->right); } } void pretree() { pretree(root); } /* 函数名:midtree 函数作用:中序遍历 参数:my_rbnode<T>* node(根节点) 返回值:无*/ void midtree(my_rbnode<T>* node) { if (node != NULL) { midtree(node->left); cout<<node->data<<'\t'; if (node->colour == BLACK) { cout<<"黑色"<<endl; } else { cout<<"红色"<<endl; } midtree(node->right); } } void midtree() { midtree(root); } /* 函数名:lasttree 函数作用:后序遍历 参数:my_rbnode<T>* node(根节点) 返回值:无*/ void lasttree(my_rbnode<T>* node) { if (node != NULL) { lasttree(node->left); lasttree(node->right); cout<<node->data<<'\t'; if (node->colour == BLACK) { cout<<"黑色"<<endl; } else { cout<<"红色"<<endl; } } } void lasttree() { lasttree(root); } private: my_rbnode<T>* root; };
相关文章推荐
- 中国剩余定理的解析及记忆(扩展欧几里得算法的运用)
- 素数表的快速建立,合数分解,1-2^31内某个长度小于10w的区间素数筛选的三个模板及解析
- 线段树3种基础模型的理解和记忆(任意区间求和,任意区间的所有数加上相同数(懒操作),任意区间所有数变成同一个值再求和)
- POJ c++ 程序设计 第五周 Part1
- POJ c++ 程序设计编程题第4周 三
- 字符编辑技术C语言实现
- 字符编辑技术C语言实现
- 字符编辑技术C语言实现
- 收藏C++ STL 使用的博文
- Microsoft Visual C++运行库合集下载(静默安装)
- 用std::pair做Unordered_map的key(C++)
- c++中的static
- C++中switch 语句中的变量声明和
- c++作业4
- c++第五次实验
- C++按行读取文件内容,储存在数组中
- C语言strtok()函数:字符串分割
- C++ 使用smtp协议发送邮件的简单实现
- [C++]Virtual_World_1(练习)
- C语言中冒泡法、选择法、插入法三种常见排序算法分析