red_black_tree的一个实现(c/c++)
来源:互联网 发布:出库软件哪个好 编辑:程序博客网 时间:2024/06/10 14:39
参考《STL源码剖析》, 博客:http://blog.csdn.net/spch2008/article/details/9338923
#ifndef MY_RB_TREE_H#define MY_RB_TREE_H#include<iostream>#include<cstddef>using namespace std;#define t_classes <typename Key,typename Value,typename KeyOfValue,typename Compare> #define classes <Key,Value,KeyOfValue,Compare> typedef bool rb_tree_color_type;const rb_tree_color_type rb_tree_red = false;const rb_tree_color_type rb_tree_black = true;struct rb_tree_node_base{ typedef rb_tree_color_type color_type; typedef rb_tree_node_base *base_ptr; color_type color; base_ptr parent; base_ptr left; base_ptr right; static base_ptr minimum(base_ptr x){ while(x -> left != NULL) x = x -> left; return x; } static base_ptr maximum(base_ptr x){ while(x -> right != NULL) x = x -> right; return x; } base_ptr increment(){ base_ptr x = this; if(x->right != NULL){ x = x->right; while(x->left != NULL) x = x->left; }else{ base_ptr y = x ->parent; while(x == y->right){ x = y; y = y->parent; } if(x->right != y) //y != header else return header x = y; } return x; } base_ptr decrement(){ base_ptr x = this; if(x->color == rb_tree_red && x->parent->parent == x){ //x == header x = x->right; }else if(x ->left != NULL){ base_ptr y = x->left; while(y->right != NULL) y = y->right; x = y; }else{ base_ptr y = x->parent; while(x == y->left){ x = y; y = y->parent; } x = y; } return x; }};template <class Value>struct __rb_tree_node: public rb_tree_node_base{ typedef __rb_tree_node<Value>* link_type; Value value_field;};//KeyOfValue is a function object (functor). In this rb_tree, the value_field contains key and value actrually. We can define the structure of the value_field but we should provide this function object to extract the key from the value_field//Compare is a function object. if a < b return true else falsetemplate t_classesclass rb_tree{protected: typedef void* void_pointer; typedef rb_tree_node_base* base_ptr; typedef __rb_tree_node<Value> rb_tree_node; typedef rb_tree_color_type color_type;public: typedef Key key_type; typedef Value value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef rb_tree_node * link_type; typedef size_t size_type; typedef ptrdiff_t difference_type;protected: link_type get_node(){ return new rb_tree_node(); } void put_node(link_type p){ delete p; } link_type create_node (const value_type x){ link_type node = get_node(); //construct(&node->value_field,x); node->value_field = value_type(x); } link_type clone_node(link_type x){ link_type tmp = creat_node(x->value_field); tmp->color = x->color; tmp->left = NULL; tmp->right = NULL; return tmp; }//if you used alloc and free in c, it should destroy the object first then release the memory void destroy_node(link_type p){ put_node(p); }protected: size_type node_count; //number of nodes link_type header; //this is an extra node for convinience, its parent is the head,left is the left most and right child is the right most node Compare key_compare; //a compare function object (functor) link_type& root() const {return (link_type &) header->parent; } link_type& leftmost() const {return (link_type &) header->left; } link_type& rightmost() const {return (link_type &) header->right; } static link_type& left(link_type x){ return (link_type&)(x->left);} static link_type& right(link_type x){ return (link_type&)(x->right);} static link_type& parent(link_type x){ return (link_type&)(x->parent);} static reference value(link_type x){ return x->value_field;} static const Key key(link_type x){ return KeyOfValue()(value(x));} static color_type& color(link_type x){ return (color_type&)(x->color);} static link_type minimum(link_type x){ return (link_type) rb_tree_node_base::minimum(x); } static link_type maximum(link_type x){ return (link_type) rb_tree_node_base::maximum(x); }private: link_type insert(base_ptr x,base_ptr y,const value_type & v); void init(){ header = get_node(); color(header) = rb_tree_red; root() = 0; leftmost() = header; rightmost() = header; } void del_tree(link_type &root);public: rb_tree(const Compare& comp = Compare()):node_count(0),key_compare(comp){init();} ~rb_tree(){ clear(); put_node(header); }// rb_tree<Key, Value, KeyOfValue, Compare> & operator= (const rb_tree<Key,Value,KeyOfValue,Compare>& x); Compare key_comp()const{return key_compare;} bool empty(){ return node_count == 0; } size_type size() const {return node_count;}public: pair<link_type,bool> insert_unique(const value_type& v); link_type insert_equal(const value_type& x); link_type find(const key_type& v); void del(link_type& x); void clear(); private: //void rb_tree_rebalance(rb_tree_node_base* x,rb_tree_node_base*& root);};template t_classesvoid rb_tree classes ::del_tree(link_type& root){ if(root == NULL) return; del_tree(left(root)); del_tree(right(root)); put_node(root);}template t_classesvoid rb_tree classes ::clear(){ if(node_count > 0){ del_tree(root()); node_count = 0; root() = NULL; leftmost() = header; rightmost() = header; }}//x is position to insert value v. y is the parent of the node of the position.template t_classestypename rb_tree classes ::link_typerb_tree classes ::insert(base_ptr _x,base_ptr _y,const value_type & v){ link_type x = (link_type) _x; link_type y = (link_type) _y; link_type z; //tree empty or x not leaf or cur_key < key_y, insert to left child if(y == header || x != 0 || key_compare(KeyOfValue()(v), key(y))){ z = create_node(v); left(y) = z; if(y == header){ root() = z; rightmost() = z; }else if(y == leftmost()) leftmost() = z; }else{ //right child z = create_node(v); right(y) = z; if(y == rightmost()) rightmost() = z; } parent(z) = y; left(z) = right(z) = NULL; rb_tree_rebalance(z,header->parent); ++node_count; return z;}template t_classespair<typename rb_tree classes ::link_type,bool>rb_tree classes ::insert_unique(const value_type& v){ link_type y = header; link_type x = root(); bool comp = true; while(x != 0){ y = x; comp = key_compare(KeyOfValue()(v),key(x)); x = comp ? left(x) : right(x); //less than or not } link_type j = y; //after while, y is the parent of x, and x is the position to insert if(comp){ //insert to the left if(j == leftmost()) return pair<link_type,bool>(insert(x,y,v),true); else j = (link_type)j->decrement(); } if(key_compare(key(j), KeyOfValue()(v))) return pair<link_type,bool>(insert(x,y,v),true); //Value v was exist return pair<link_type,bool> (j,false); }template t_classestypename rb_tree classes::link_type rb_tree classes ::insert_equal(const value_type& v){ link_type y = header; link_type x = root(); while(x != 0){ y = x; x = key_compare(KeyOfValue()(v),key(x)) ? left(x) : right(x); } return insert(x,y,v);}template t_classestypename rb_tree classes::link_typerb_tree classes ::find(const key_type& k){ link_type cur = root(); if(cur == header) return NULL; while(cur != NULL){ bool comp1 = key_compare(k,key(cur)); bool comp2 = key_compare(key(cur),k); if(comp1 == comp2) break; if(comp1) cur = left(cur); else cur = right(cur); } return cur;}inline voidrb_tree_rotate_left(rb_tree_node_base* x,rb_tree_node_base*& root){ rb_tree_node_base*y = x->right; x->right = y->left; if(y->left != NULL) y->left->parent = x; y->parent = x->parent; if(x == root) root = y; else if(x == x->parent->left) x->parent->left = y; else x->parent->right = y; x->left = x; x->parent = y;}inline voidrb_tree_rotate_right(rb_tree_node_base* x,rb_tree_node_base*& root){ rb_tree_node_base*y = x->left; x->left = y->right; if(y->right != NULL) y->right->parent = x; y->parent = x->parent; if(x == root) root = y; else if(x == x->parent->right) x->parent->right = y; else x->parent->left = y; y->right = x; x->parent = y;}void rb_tree_rebalance(rb_tree_node_base* x,rb_tree_node_base*& root){ x->color = rb_tree_red; while(x != root && x->parent->color == rb_tree_red){ if(x->parent == x->parent->parent->left){ //parent is the left child of grandpar rb_tree_node_base* y = x->parent->parent->right; if(y && y->color == rb_tree_red){ //uncle is red x->parent->color = rb_tree_black; y->color = rb_tree_black; x->parent->parent->color = rb_tree_red; x = x->parent->parent; }else{ //no uncle or uncle is black if(x == x->parent->right){ //x is the right child x = x->parent; rb_tree_rotate_left(x,root); } x->parent->color = rb_tree_black; x->parent->parent->color = rb_tree_red; rb_tree_rotate_right(x->parent->parent,root); } }else{ ///parent is the right child of grandpar rb_tree_node_base *y = x->parent->parent->left; if(y && y->color == rb_tree_red){ x->parent->color = rb_tree_black; y->color = rb_tree_black; x->parent->parent->color = rb_tree_red; x = x->parent->parent; }else{ if(x == x->parent->left){ x = x->parent; rb_tree_rotate_right(x,root); } x->parent->color = rb_tree_black; x->parent->parent->color = rb_tree_red; rb_tree_rotate_left(x->parent->parent,root); } } }}void rb_tree_rebalance_for_del(rb_tree_node_base *x,rb_tree_node_base* x_parent,rb_tree_node_base* root){ while (x != root && (x == 0 || x->color == rb_tree_black)) if (x == x_parent->left) { rb_tree_node_base* w = x_parent->right; //case 1 if (w->color == rb_tree_red) { w->color = rb_tree_black; x_parent->color = rb_tree_red; rb_tree_rotate_left(x_parent, root); w = x_parent->right; } //case 2 if ((w->left == NULL || w->left->color == rb_tree_black) && (w->right == NULL || w->right->color == rb_tree_black)) { w->color = rb_tree_red; x = x_parent; x_parent = x_parent->parent; } else { //case 3 if (w->right == 0 || w->right->color == rb_tree_black) { if (w->left) w->left->color = rb_tree_black; w->color = rb_tree_red; rb_tree_rotate_right(w, root); w = x_parent->right; } //case 4 w->color = x_parent->color; x_parent->color = rb_tree_black; if (w->right) w->right->color = rb_tree_black; rb_tree_rotate_left(x_parent, root); break; } }else{ rb_tree_node_base* w = x_parent->left; //case 1 if (w->color == rb_tree_red) { w->color = rb_tree_black; x_parent->color = rb_tree_red; rb_tree_rotate_right(x_parent, root); w = x_parent->left; } //case 2 if ((w->left == NULL || w->left->color == rb_tree_black) && (w->right == NULL || w->right->color == rb_tree_black)) { w->color = rb_tree_red; x = x_parent; x_parent = x_parent->parent; } else { //case 3 if (w->left == NULL || w->left->color == rb_tree_black) { if (w->right) w->right->color = rb_tree_black; w->color = rb_tree_red; rb_tree_rotate_left(w, root); w = x_parent->left; } //case 4 w->color = x_parent->color; x_parent->color = rb_tree_black; if (w->left) w->left->color = rb_tree_black; rb_tree_rotate_right(x_parent, root); break; } } if (x != NULL) x->color = rb_tree_black; }template t_classesvoid rb_tree classes ::del(link_type& x){ if(x == NULL) return; if(node_count == 1){ put_node(x); root() = NULL; leftmost() = header; rightmost() = header; node_count = 0; return; } link_type y = x; if(right(y) != NULL){ y = right(y); while(left(y) != NULL) y = left(y); } swap(value(x),value(y)); x = y; if(left(x) != NULL) y = left(x); else if(right(x)) y = right(x); link_type par = parent(x); if(x != y){ if(x == root()){ root() = y; leftmost() = y; rightmost() = y; parent(y) = parent(x); }else{ if(x == par->left){ left(par) = y; parent(y) = par; }else{ right(par) = y; parent(y) = par; } } }else{ if(left(par) == x) left(par) = NULL; else right(par) = NULL; y = NULL; } if(color(x) == rb_tree_black) rb_tree_rebalance_for_del(y,par,root()); --node_count; put_node(x);}#endif
简单的测试文件:
#include "rb_tree.h"struct KeyOfValue{ int operator()(int v){return v;}};struct Compare{ bool operator()(const int &a,const int &b){return a<b;}};typedef int Key;typedef int Value;int main(){ rb_tree<Key,Value,KeyOfValue,Compare> tree; tree.insert_unique(3); cout<<tree.size()<<endl; tree.insert_unique(4); cout<<tree.size()<<endl; tree.insert_unique(3); cout<<tree.size()<<endl; tree.insert_unique(5); cout<<tree.size()<<endl; tree.insert_unique(1); cout<<tree.size()<<endl; tree.insert_equal(3); cout<<tree.size()<<endl; rb_tree<Key,Value,KeyOfValue,Compare>::link_type a = tree.find(3); rb_tree<Key,Value,KeyOfValue,Compare>::link_type b = tree.find(2); cout<<b<<int(NULL)<<endl; tree.del(a); tree.del(b); cout<<tree.size()<<endl;return 0;}
阅读全文
0 0
- red_black_tree的一个实现(c/c++)
- 红黑树(red_black_tree)的c语言实现
- 一个算法的C实现
- 红黑树的一个C实现
- 一个双链表的C实现
- 一个双链表的C实现
- C-一个栈的实现
- 一个简单的http_server的c实现
- 【c++】实现一个类
- C实现一个进度条
- c实现的一个经典链表
- 用C实现的一个cstring
- 一个简单的HashMap C语言实现
- [C#]StringWriter实现的一个功能
- 一个urlencode/urldecode的C实现
- C语言一个库函数的实现
- C语言一个单链表的实现
- 一个简单的HashMap C语言实现
- 邮件发送代码片段
- protocol .proto文件转.java文件
- Unity_NGUI基础控件_ScrollView_042
- Hive集合数据类型
- linux zip,linux下打包zip文件
- red_black_tree的一个实现(c/c++)
- 特定式子的非线性拟合(使用于数据较少的的时候)
- 查看进程所消耗的内存脚本
- Keras实现一个简单的Regression回归
- 模板方法模式--大步骤一样小实现不同
- 手把手叫你如何集成高德地图,实现地图显示、定位蓝点、大头针显示、获取周围地点信息等
- “多进程”,你不知道的事(下)
- Window系统中MySql 5.7.19 忘记密码该怎么改回来
- HTML-子div在父div中垂直居中