zoukankan      html  css  js  c++  java
  • 关联式容器

    容器rb_tree

    Red-Black tree(红黑树)是平衡二叉搜索树(balanaced binary search tree)中常被使用的一种。平衡二叉搜索树的特征:排列规则有利于search和insert,并保持适度平衡——无任何节点过深。

    rb_tree提供遍历操作及iterators。按正常规则(++ite)遍历,便能获得排序状态。

    我们不应使用rb_tree的iterators改变元素值(因为元素有其排列规则)。编程层面并未阻值此事。如此设计是正确的,因为rb_tree即将为set和map服务(作为其底部支撑),而map允许元素的data被改变,只有元素的key才是不可被改变的。

    rb_tree提供两种insert操作:insert_unique()和insert_equal()前者表示节点的key一定在整个tree中独一无二,否则安装失败,后者表示节点的key可以重复。

    rb_tree的实现代码

    namespace rb_tree{
    
    	template <class Key, //键
    			  class Value, //key与data组合称为data
    			  class KeyOfValue, //如何从value中取出data
    			  class Compare,  //key之间的比较方法
    			  class Alloc = alloc> //分配器
    	class rb_tree {
    	protected:
    		typedef __rb_tree_node<Value> rb_tree_node;
    	public:
    		typedef rb_tree_node* link_type;
    	protected:
    		//RB_tree只以三个资料表现它自己
    		size_type node_count; //rb_tree的大小 4
    		link_type header;  //大小为4
    		Compare key_compaer; //key的比较规则,应该是仿函数对象 大小为1
    
    	};
    };
    
    

    rb_tree的结构

    rb_tree的noede结构

    _M_color: _Rb_tree_color //节点颜色 枚举类型
    _M_parent: _Base_Ptr //指向父节点的指针
    _M_right: _Base_Ptr //指向右孩子的指针
    _M_right: _Base_ptr //指向左孩子的指针
    

    所以一共是16个字节

    set/multiset

    set的定义

    set/multiset是以rb-tree为底层结构,因此元素有自动排序的性质。排序的依据是key,而set/multiset元素的key和value合二为一。

    set/multiset提供遍历操作,以及iterators.按照正常操作就可以获得排序状态。

    我们无法使用set/multiset的iterators改变元素的值(因为key有其严谨的排序规则)。set/multiset的iterator是其改变底部RB-tree的const iterator,就是为了禁止user对元素赋值。

    set元素的key独一无二,因此其insert()用的是rb_tree的insert_unique();

    multiset的key可以重复,因此insert()用的是rb_tree的insert_equal();

    set的代码实现

    namespace set_test {
    	template <class Key,
    			  class Compare = less<Key>,
    			  class Alloc = alloc>
    	class set {
    	public:
    		//typedefs 
    		typedef Key key_type;
    		typedef Key value_type;
    		typedef Compare key_compare;
    		typedef Compare value_compare;
    	private:
    		typedef rb_tree<key_type, value_type, identity<value_type>, key_compare, Alloc>rep_type;
    		rep_type t;
    	public:
    		typedef typename rep_type::const_iterator iterator;
    	};
    }
    

    set的操作分析

    当你拿set的迭代器时,拿到的是const_iterator,而且是rb_tree的迭代器,所以set不允许通过迭代器改变key.

    set的所有操作都是通过调用底部的rb_tree来完成的,和stack和queue一样(调用deque)

    set内部数据结构图

    map/multimap

    map的性质

    map/multimap是以rb_tree为底层结构,因此有元素自动排序特性,排序的依据是key.

    map/multimap提供遍历操作以及iterators,按正常规则遍历,便能获得排序状态。

    我们无法使用map/multimap的iterators改变元素的key,但可以用它来改变元素的data,因此map/multimap内部自动将user指定的 key type设为const,如此便能禁止user对元素的key赋值。

    map元素的key必须独一无二,因此insert使用的是rb_tree的insert_unique()

    multimap的key是可以重复的,因此insert使用的是rb_tree的insert_equal()

    map的实现

    #pragma once
    template <class Key, class T,class Compare = less<key>,class Alloc = alloc>
    class map {
    public:
    	typedef Key key_type;
    	typedef T data_type;
    	typedef T mapped_type;
    	typedef pair<const Key, T> value_type;
    	typedef Compare key_compare;
    private:
    	typedef rb_tree<key_type, value_type,
    		selectlst<value_type>, key_compare, Alloc> rep_type;
    	rep_type t;
    public:
    	typedef typename rep_type::iterator iterator;
    };
    
    

    map的内部数据结构图

    map数据结构的组成

    map<int,string>imap;
    当我们输入上述代码时:
    pair<const key,T>value_type; 将传入的两个参数合并成为一个map,且pair的第一个元素为const.
    
  • 相关阅读:
    关于android4.3 Intel X86 Atom System Image的下载
    dp和px以及sp
    Android项目结构分析
    Performance Testing
    Modifying a Request or Response
    Log Sessions to Local Database
    The Web Sessions List
    Using QuickExec
    AutoResponder Reference
    Fiddler Session标志
  • 原文地址:https://www.cnblogs.com/ccpang/p/12271912.html
Copyright © 2011-2022 走看看