红黑树C++实现
2015-09-19 14:26
633 查看
最近一直在复习面试的内容,会不断的记录相关自己看过或者写过的内容,这也是自己的收获或经历,以后查询也比较方便。
红黑树的性质不说了,直接贴代码上传。
红黑树的性质不说了,直接贴代码上传。
/* * rbtree.h * 1. 每个节点是红色或者黑色 * 2. 根节点是黑色 * 3. 每个叶子节点是黑色(该叶子节点就空的节点) * 4. 如果一个节点是红色,则它的两个子节点是黑色的 * 5.对每个节点,从该节点道其他所有后代的叶子节点的简单路径上,均包含相同数目的黑色节点 * */ #ifndef SRC_RBTREE_H_ #define SRC_RBTREE_H_ #include<iostream> #include<queue> using namespace std; enum colors{ RED,BLACK}; typedef int color_type; namespace red_black_tree{ struct rb_tree_base{ struct rb_tree_base * parent; struct rb_tree_base * left; struct rb_tree_base * right; color_type color; }; template<class T> struct rb_tree_node:public rb_tree_base{ T data; typedef rb_tree_node<T>* link_type; }; template<class Value> class rb_tree{ public: typedef rb_tree_base* rb_ptr; typedef typename rb_tree_node<Value>::link_type link_type; typedef rb_tree_node<Value> tree_node; private: rb_ptr head; private: bool _right_rotate(rb_ptr root); bool _left_rotate(rb_ptr root); rb_ptr _get_node(const Value& e) const; bool _insert_fix_up(rb_ptr current_ptr); bool _erase_fix_up(rb_ptr current_ptr,rb_ptr parent_ptr); void _preOrder(rb_ptr root) const; rb_ptr _successor(rb_ptr current_ptr) const; public: rb_tree(); ~rb_tree(); bool insert(const Value &e); bool empty() const; bool erase(const Value &e); rb_ptr find(const Value &e); void levelOrder() const; void preOrder() const; }; template<class Value> rb_tree<Value>::rb_tree() { head = new tree_node(); head->left=head; head->right=head; head->parent=head; head->color=BLACK; } template<class Value> rb_tree<Value>::~rb_tree() { } template<class Value> bool rb_tree<Value>::insert(const Value& e) { rb_ptr insert_ptr =_get_node(e); if(head->parent ==head){ head->parent=insert_ptr; insert_ptr->parent=head; insert_ptr->color=BLACK; return true; } rb_ptr root_ptr=head->parent; rb_ptr root_remember=nullptr; while(root_ptr){ root_remember=root_ptr; if(link_type(insert_ptr)->data<=link_type(root_ptr)->data) root_ptr=root_ptr->left; else root_ptr=root_ptr->right; } insert_ptr->parent=root_remember; if(link_type(insert_ptr)->data <= link_type(root_remember)->data ) root_remember->left=insert_ptr; else if(link_type(insert_ptr)->data >link_type( root_remember)->data) root_remember->right=insert_ptr; bool ret =_insert_fix_up(insert_ptr); return ret; } template<class Value> bool rb_tree<Value>::empty() const { return head->parent==head; } template<class Value> bool rb_tree<Value>::erase(const Value& e) { rb_ptr erase_ptr = find(e); if(!erase_ptr) return false; int erase_color =erase_ptr->color; rb_ptr fix_up_ptr=nullptr; rb_ptr fix_up_parent_ptr=nullptr; if(erase_ptr){ if(!erase_ptr->left&&!erase_ptr->right){//叶子节点 if(erase_ptr==erase_ptr->parent->left){ erase_ptr->parent->left=nullptr; fix_up_parent_ptr= erase_ptr->parent; } if(erase_ptr==erase_ptr->parent->right){ erase_ptr->parent->right=nullptr; fix_up_parent_ptr= erase_ptr->parent; } if(erase_ptr==head->parent){ head->parent=head; fix_up_parent_ptr=head; } erase_color =erase_ptr->color; delete erase_ptr; }else if(erase_ptr->right){ rb_ptr successor_ptr =_successor(erase_ptr);//left一定为空 link_type(erase_ptr)->data=link_type(successor_ptr)->data; if(successor_ptr==successor_ptr->parent->left) successor_ptr->parent->left=successor_ptr->right; if(successor_ptr==successor_ptr->parent->right) successor_ptr->parent->right=successor_ptr->right; if(successor_ptr->right) successor_ptr->right->parent=successor_ptr->parent; fix_up_ptr=successor_ptr->right; fix_up_parent_ptr=successor_ptr->parent; erase_color=successor_ptr->color; delete successor_ptr; }else{//直接用左子树代替,或者找到后继节点代替也行,但比较麻烦,效果一样。 if(erase_ptr ==erase_ptr->parent->left) erase_ptr->parent->left=erase_ptr->left; else erase_ptr->parent->right=erase_ptr->left; erase_ptr->left->parent=erase_ptr->parent; fix_up_ptr=erase_ptr->left; fix_up_parent_ptr=erase_ptr->parent; erase_color=erase_ptr->color; delete erase_ptr; } if(erase_color==BLACK) return _erase_fix_up(fix_up_ptr,fix_up_parent_ptr); } return false; } template<class Value> typename rb_tree<Value>::rb_ptr rb_tree<Value>::find(const Value& e) { rb_ptr root=head->parent; if(head->parent !=head){ while(root){ if(link_type(root)->data == e) return root; else if( e<=link_type(root)->data){ root=root->left; }else root=root->right; } } return nullptr; } /** * current_ptr节点的祖父节点一定是黑色,因为它的父节点是红色的,所以性质4只在插入节点和该父节点被破坏 * 情况1:叔节节点uncle_ptr是红色; * 1)父节点parent_ptr和叔节点uncle_ptr的颜色改为黑色,祖父节点grandfather_ptr的颜色改为红色 * 2)把current_ptr节点设置为grandfather,因为只有祖父节点和祖父节点的父节点之间会违法性质。 * 情况2:叔父节点uncle_ptr是黑色,或者unclue_ptr为空; * 1)根据根据当前节点的位置,把当前节点current_ptr设置为parent_ptr,对其左旋或右旋。 * 情况3:叔父节点存在或者叔父节点颜色为黑色,且父右儿右关系(或父左儿左) 1)把父节点颜色设为黑色,把祖父颜色设为红色 2)对祖父节点进行左旋(或右旋) * */ template<class Value> bool rb_tree<Value>:: _insert_fix_up(rb_ptr current_ptr){ while(current_ptr->parent->color ==RED){ rb_ptr parent_ptr =current_ptr->parent; rb_ptr grandfather_ptr=parent_ptr->parent; if(parent_ptr ==grandfather_ptr->left){ rb_ptr uncle_ptr=parent_ptr->parent->right; if(uncle_ptr && uncle_ptr->color==RED){ parent_ptr->color=BLACK; uncle_ptr->color=BLACK; grandfather_ptr->color=RED; current_ptr=grandfather_ptr; }else if(current_ptr ==parent_ptr->right){ current_ptr=parent_ptr; _left_rotate(current_ptr); }else{ current_ptr->parent->color=BLACK; current_ptr->parent->parent->color=RED; _right_rotate(current_ptr->parent->parent); } }else{ rb_ptr uncle_ptr=parent_ptr->parent->left; if(uncle_ptr && uncle_ptr->color==RED){ parent_ptr->color=BLACK; uncle_ptr->color=BLACK; grandfather_ptr->color=RED; current_ptr=grandfather_ptr; }else if(current_ptr ==parent_ptr->left){//uncle_ptr->color 是BLACK,或者uncle_ptr为空 current_ptr=parent_ptr; _right_rotate(current_ptr);//其实就是转换为父右儿右的情况 }else{//父右儿右 current_ptr->parent->color=BLACK; current_ptr->parent->parent->color=RED; _left_rotate(current_ptr->parent->parent); } } } head->parent->color=BLACK; return true; } template<class Value> bool rb_tree<Value>::_erase_fix_up(rb_ptr current_ptr,rb_ptr parent_ptr){ while((!current_ptr||current_ptr->color==BLACK)&¤t_ptr!=head->parent){ if(parent_ptr->left ==current_ptr){ rb_ptr brother_ptr = parent_ptr->right; if(brother_ptr->color ==RED){ parent_ptr->color=RED; brother_ptr->color=BLACK; _left_rotate(brother_ptr); brother_ptr=current_ptr->parent->right; } if(brother_ptr->color==BLACK && (!brother_ptr->left ||brother_ptr->left->color ==BLACK)&& (!brother_ptr->right || brother_ptr->right->color ==BLACK)){ brother_ptr->color=RED; current_ptr=parent_ptr; parent_ptr=current_ptr->parent; }else { if(brother_ptr->color==BLACK && (!brother_ptr->right||brother_ptr->right->color==BLACK)){//右侄黑,左侄红 brother_ptr->left->color=BLACK; brother_ptr->color=RED; _right_rotate(brother_ptr); brother_ptr=parent_ptr->right; }//右侄红色 brother_ptr->color=parent_ptr->color; parent_ptr->color=BLACK; if(brother_ptr->right) brother_ptr->right->color=BLACK; _left_rotate(parent_ptr); current_ptr=head->parent; } }else{ rb_ptr brother_ptr = parent_ptr->left; if(brother_ptr->color ==RED){ parent_ptr->color=RED; brother_ptr->color=BLACK; _right_rotate(brother_ptr); brother_ptr=current_ptr->parent->left; } if(brother_ptr->color==BLACK && (!brother_ptr->left ||brother_ptr->left->color ==BLACK)&& (!brother_ptr->right || brother_ptr->right->color ==BLACK)){ brother_ptr->color=RED; current_ptr=parent_ptr; parent_ptr=current_ptr->parent; }else { if(brother_ptr->color==BLACK && (!brother_ptr->right||brother_ptr->right->color==BLACK)){//右侄黑,左侄红 brother_ptr->left->color=BLACK; brother_ptr->color=RED; _left_rotate(brother_ptr); brother_ptr=parent_ptr->left; }//右侄红色 brother_ptr->color=parent_ptr->color; parent_ptr->color=BLACK; if(brother_ptr->left) brother_ptr->left->color=BLACK; _right_rotate(parent_ptr); current_ptr=head->parent; } } } if (current_ptr) current_ptr->color=BLACK; return true; } template<class Value> typename rb_tree<Value>::rb_ptr rb_tree<Value>::_successor(rb_ptr current_ptr) const{ rb_ptr right_child_ptr = current_ptr->right; if(right_child_ptr){ rb_ptr left_ptr =right_child_ptr->left; rb_ptr left_remember_ptr; if(left_ptr){ while(left_ptr){ left_remember_ptr =left_ptr; left_ptr=left_ptr->left; } return left_remember_ptr; } return right_child_ptr; }else{ rb_ptr parent_ptr=current_ptr->parent; while(current_ptr ==parent_ptr->right){ current_ptr=parent_ptr; parent_ptr=parent_ptr->parent; } return parent_ptr; } return nullptr; } template<class Value> typename rb_tree<Value>::rb_ptr rb_tree<Value>::_get_node(const Value& e) const { rb_ptr insert_ptr = new tree_node(); link_type(insert_ptr)->data=e; insert_ptr->parent=nullptr; insert_ptr->left=nullptr; insert_ptr->right=nullptr; insert_ptr->color=RED; return insert_ptr; } template<class Value> bool rb_tree<Value>::_right_rotate(rb_ptr root){ if(root->left!=nullptr){ rb_ptr left_child_ptr=root->left; root->left=left_child_ptr->right; if(left_child_ptr->right !=nullptr) left_child_ptr->right->parent=root; left_child_ptr->right=root; left_child_ptr->parent=root->parent; if(root->parent->left ==root) root->parent->left=left_child_ptr; else if(root->parent->right==root) root->parent->right=left_child_ptr; if(root->parent==head){ root->parent->parent=left_child_ptr; } root->parent=left_child_ptr; return true; } return false; } template<class Value> bool rb_tree< Value >::_left_rotate(rb_ptr root){ if(root->right!=nullptr){ rb_ptr right_child_ptr=root->right; root->right=right_child_ptr->left; if(right_child_ptr->left != nullptr) right_child_ptr->left->parent=root; right_child_ptr->left=root; right_child_ptr->parent=root->parent; if(root->parent->left ==root) root->parent->left=right_child_ptr; else if(root->parent->right ==root) root->parent->right=right_child_ptr; if(root->parent==head){ root->parent->parent=right_child_ptr; } root->parent=right_child_ptr; return true; } return false; } template<class Value> void rb_tree<Value>::levelOrder() const { rb_ptr root =head->parent; queue<rb_ptr> q; if(head->parent !=head){ q.push(root); while(!q.empty()){ rb_ptr visit_ptr = q.front(); cout<<"data: "<<link_type(visit_ptr)->data<<" color: "<<((visit_ptr->color==0)?"RED":"BLACK")<<endl; if(visit_ptr->left) q.push(visit_ptr->left); if(visit_ptr->right) q.push(visit_ptr->right); q.pop(); } } } template<class Value> void rb_tree<Value>:: _preOrder(rb_ptr root) const{ if(root){ cout<<"data: "<<link_type(root)->data<<" color: " <<((root->color==0)?"RED":"BLACK")<<endl; _preOrder(root->left); _preOrder(root->right); } } template<class Value> void rb_tree<Value>:: preOrder() const{ _preOrder(head->parent); } } //#include "rbtree.cpp" #endif /* SRC_RBTREE_H_ */
相关文章推荐
- 关于C++的接口类
- VC++ unicode下读取unicode CFile::typeUnicodetxt的数据
- 黑马程序员独特的放松方式 "小巧玲珑的C语言游戏--井字游戏"
- 【c++ templates读书笔记】【1】函数模板
- 【c++ templates读书笔记】【1】函数模板
- C/C++:C++友元类
- C语言冒泡排序法
- C++成员变量的初始化顺序问题
- Item 31:最小化文件之间的编译依赖 Effective C++笔记
- C语言 printf 格式化 输出 右对齐补零
- c++程序设计原理与实践---(3)类的派生和虚函数
- 1.c++中与oc中类和对象创建及访问
- c++ primer plus第十二章-动态内存和类、复制构造函数
- 单链表C语言的实现
- 【C语言】编译预处理
- c++面试题之打印1到最大的n位数
- C++面试之GetMemory问题
- CVTE C/C++开发工程师笔试题(二)
- C++友元函数
- CVTE C/C++开发工程师笔试题(一)