zoukankan      html  css  js  c++  java
  • STL红黑树

    红黑树

    相关概念

    img

    1 rb_tree 是一种高度平衡的搜索二叉树,其元素排列的规则有利于 search 和 insert,并同时保持适度的平衡。
    2 rb_tree 提供遍历操作以及 iterator。元素放入后有一定的排列规则,按正常规则(++ iter)迭代器遍历时为输出为排序状态(sorted)。
    3 不应使用 rb_tree 的 iterator 改变元素值(影响原有排序)。语法层面是不禁止这种操作的。如此设计的原因是,由 rb_tree 实现的 map 其 key 值(排序以 key 值为依据) 是不能改动的,而通过 iterator 改变 map 的 data 值是允许的。
    4 rb_tree 提供两种 insertion 操作:insert_unique() 和 insert_equal()。 前者表示节点的 key 一定在整个 tree 中独一无二,否则安插失败(但不返回error,不做任何操作);后者表示节点的 key 可重复。

    实现

    img

    Key 为 key 值的类型,Value 为放入的整个元素节点的数据类型、

    KeyOfValue 为从 Value 中 取得 key 值的方法,此处应为一个函数对象、(例:identity、select1st<value_type>)

    Compare 为比较两个元素大小的函数对象。

    img

    测试代码

    #include <iostream>
    //添加set头文件或者map头文件,否则_Rb_tree找不到定义
    #include <set>
    
    using namespace std;
    
    void Test1()
    {
    	/*
    
    	在Linux环境下可以正常调用
    	
    	_Rb_tree<int, int, _Identity<int>, less<int>> itree;
    	cout << itree.empty() << endl;  //1
    	cout << itree.size() << endl;   //0
    	
    	itree._M_insert_unique(3);
    	itree._M_insert_unique(8);
    	itree._M_insert_unique(5);
    	itree._M_insert_unique(9);
    	itree._M_insert_unique(13);
    	itree._M_insert_unique(5);  //no effect, since using insert_unique().
    	cout << itree.empty() << endl;  //0
    	cout << itree.size() << endl;   //5
    	cout << itree.count(5) << endl; //1
    	
    	itree._M_insert_equal(5);
    	itree._M_insert_equal(5);
    	cout << itree.size() << endl;   //7, since using insert_equal().
    	cout << itree.count(5) << endl; //3 
    	
    		*/
    
    }
    
    
    
    int main(int argc, char *argv[])
    {
    	Test1();
        return 0;
    }
    

    map/multimap-rbtree

    相关概念

    1. map/multimap 以 rb_tree 为底层结构,因此有元素自动排序特性。排序的依据是 key。
    2. key 不能修改,data 可以修改。map/multimap 内部自动将 user 指定的 key type 设为 const,如此便能禁止 user 对 key 的赋值。

    实现

    img

    1. select1st<pair<const int, string>> 从 Value 中 取得 key 值的方法,即取 pair 中的第一个类型 int 作为 key。

    2. map 的 iterator 就是 rb_tree 的迭代器。其中 pair 的第一个模板参数为 const int。

    img

    map 独有的 operator [ ]

    Allows for easy lookup with the subscript (@c[ ]) operator. Returns data asscoiated with the key specified subscript. If the key does not exist, a pair with that key is created using default values, which is then returned.
    如果 key 值不存在,则生成一个带有默认 data 值的 value安插进去

    img

    lower_bound() 是二分查找的一种,试图在排序过的元素中寻找 value 。若查找范围内拥有与 value 相等的元素(s),便返回一个 iterator 指向其中第一个元素。如果没有这样的元素存在,便返回“假设该元素存在是应该出现的位置”。也就是说它会返回 iterator 指向第一个不小于 value 的元素。如果 value 大于查找范围内的任何元素,将返回 last 。换句话说,lower_bound 返回的是“不破坏排序得以安插 value 的第一个适当位置”。

    而 operator [ ] 最终返回的是这个位置的 .second引用,可以利用这个引用直接赋值,相当于 insert() 操作 。

    set/multiset-rbtree

    相关概念

    1 set/multiset 以 rb_tree 为底层结构,因此有元素自动排序特性。排序的依據是 key,set/multiset 的 value 就是 key。
    2 set/multiset 提供遍历操作以及 iterator。元素放入后有一定的排列规则,按正常规则(++ iter)迭代器遍历时为输出为排序状态(sorted)。
    3 无法使用 set/multiset 的 iterator 改变元素值(因为 key 就是 value)。其 iterator 底层实现是 RBtree 的 const iterator,禁止对元素赋值。
    4 set 的元素不允许重复,所以 insert() 调用 insert_unique()。multiset 的元素可以重复,所以 insert() 调用 insert_equal()。

    实现

    img

    1 rep_type (定义了一个成员变量)说明了其底层实现为一个红黑树。其红黑树的5个模板参数都可由 set 的三个模板参数得来。
    2 无法使用 set/multiset 的 iterator 改变元素值(key 就是 value),因为 set 的 iterator 是 const 不允许通过它改变元素。
    3 set 的所有操作都转调用底层 t 的类方法。

    img

    注意事项

    map和set的迭代器类型以及相关操作的时间复杂度

    双向迭代器
    随机访问每个元素 O(logn)
    末尾插入删除元素 O(logn)
    中间或开头删插元素 O(logn)

    为何map和set的插入删除效率比用其他序列容器高?

    map和set中所有元素都是以节点的形式来存储,插入删除操作只涉及到指针的转换,无需像vetor和deque一样考虑内存重新申请与拷贝

  • 相关阅读:
    struts2 中的 result 返回类型是 json 的配置问题
    EL 表达式 取值将 < 转成 &1t 问题
    Redis 设计与实现读书笔记一 Redis List
    lhgdialog 与后台交互的对话框
    Redis 设计与实现读书笔记一 Redis字符串
    Struts2 OGNL使用详解(转)
    Struts2 中遇到的问题
    Struts2
    Linux服务器开发:工具
    fastadmin html数字验证
  • 原文地址:https://www.cnblogs.com/LuckCoder/p/14532898.html
Copyright © 2011-2022 走看看