深度探索红黑树

来源:互联网 发布:香港小鱼儿最近域名 编辑:程序博客网 时间:2024/05/22 12:22
     RB-tree是除AVl-tree之外被广泛应用的平衡二叉搜素树,AVL-tree是最早的平衡二叉树之一,在实际中应用的比较少,windows对进程地址空间的管理用到了AVL树,红黑树广泛应用在STL中,map和set都是用红黑树实现的。
     AVL-tree是一种高度平衡的二叉搜素树,造成的结果是维护这种高度平衡所付出的代价比从中获得效率收益还高,所以在实际中应用不多,更多的是用追求局部而不是严格整体平衡的红黑树。本文将结合stl中rb_tree源码分析红黑树的一些结构。
     RB-tree必须满足的规则:
        1.每个节点不是红色就是黑色
        2.根节点为黑色
        3.如果节点为红,其子节点必须为黑

        4.任一节点到叶节点的任何路径,所含黑节点的树必须相同。

  

//rb_tree的定义/*模板参数的含义:1.key 表示节点的键2.Value表示节点(key+value)3.KeyOfValue表示怎么从key中取出value4.Compare表示key的比较规则,应为要排序5.Alloc分配器*/template <class key,class Value,class KeyOfValue,class Compare,class Alloc=alloc>class rb_tree{protected:size_type node_count;  //记录数的节点数量,占4个字节大小link_type header;   //头节点,指向root节点,类似于链表的头节点,它是一个指针,占4个字节Compare key_compare; //节点的key比较规则,实际key_compare是一个函数,函数不占大小的,但实际上编译器在处理的时候会添加1个字节//根据这里的分析,rb_tree占用的大小为9个字节,考虑对齐规则,rb_tree占用的大小为12字节,可以用sizeof(rb_tree)测试验证protected:typedef __rb_tree_node<Value> rb_tree_node;...public:typedef rb_tree_node* link_type;...protected://获取节header的成员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;}//获取节点x的成员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);}...public:Compare key_comp() const{return key_compare;}iterator begin(){return leftmost();}iterator end(){return header;}bool empty() const{return node_count == 0;}size_type size() const{return node_count;}size_type max_size() const{return size_type(-1);}public://将x插入到RB-tree中,保持节点值独一无二pair<iterator, bool> insert_unique(const value_type& x);//将x插入到RB-tree中,允许节点值重复iterator insert_equal(const value_type& x);...};

   一般来说,我们不应使用rb_tree的iterators改变元素值,因为元素有其排列规则,虽然源代码阻止此事,因为rb_tree将为
set和map提供底层支持,而map运行元素的data被改变,只有key是不可以改变的
   rb_tree提供两个insertion操作:insert_unique()和iinsert_equal()前者表示节点的key一定在整个tree中独一无二,否则出入失败,后者表示节点的key可重复

        
//测试rb_treerb_tree<int, int, identity<int>, less<int>> itree;cout << itree.empty() << endl; //1cout << itree.size() << endl;//0itree.insert_unique(3);itree.insert_unique(8);itree.insert_unique(5);itree.insert_unique(9);itree.insert_unique(13);itree.insert_unique(5); //不会被插入cout << itree.empty() << endl; //0cout << itree.size() << endl;  //5cout << itree.count(5) << endl; //1itree.insert_equal(5);itree.insert_equal(5);count << itree.size() << endl; //7count << itree.count(5) << endl;//3


0 0
原创粉丝点击