C++笔记:红黑树与哈希表

1.容器rb_tree

  • 按正常规则++it遍历,便能得到排序状态
  • 不能使用rb_tree的iterators改变元素值
  • 两种插入操作:insert_unique()和insert_equal()
template <class Key, class Value, class KeyOfValue, class Compare, class Alloc=alloc>
class rb_tree
{
protected:
		typedef __rb_tree_node<Value> rb_tree_node;
public:
		typedef rb_tree_node* link_type;
protected:
		size_type node_count;
		link_type header;  // 指向红黑树节点的指针
		Compare key_compare;  // key值比较方法
};

rb_tree<int, int, identity<int>, less<int>, alloc> itree;

2.容器set,multiset

  • 元素按照key值自动排序
  • set/multiset提供遍历操作,不能使用迭代器来改变元素的Key(Key就是data)
  • set的所有操作,都在呼叫底层rb_tree的操作
template <class Key, class Compare = less<Key>, class Alloc=alloc>
class set{
public:
		typedef Key key_type;
		typedef Key value_type;
		typedef Compare key_compare;
		typedef Compare value_compare;
private:
		typedef rb_tree<key_value, value_type, identity<value_type>, key_compare, Alloc> rep_type;
		rep_type t;
public:
		typedef typename rep_type::**const_iterator** iterator;  // 为了禁止user对元素赋值

3.容器map,multimap

  • 元素按照key值自动排序
  • 提供遍历操作,不能使用迭代器来改变元素的Key。但可以用它来改变元素的data
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, select1st<value_type>, key_compare, Alloc> rep_type;
		rep_type t;
public:
		typedef typename rep_type::iterator iterator;
template<class Arg, class Result>
struct unary_function{
		typedef Arg argument_type;
		typedef Result result_type;
}

template<class Pair>
struct select1st:public unary_function<Pair, typename Pair::first_type>
{
		const typename Pair::first_type& operaor()(const Pair&x) const 
		{return x.first};
}
  • set的元素既是key也是value,修改任何一个元素都会破坏集合的有序性和唯一性,因此不允许修改。
  • map的元素是键值对,键必须保持不变以保证有序性,但值的修改不会影响有序性,因此允许修改值。

4.容器hashtable

  • rehashing:当我们需要安插的元素数目大于篮子的数目,就需要将原本的篮子数目扩充近一倍

 

template <class Value, class Key, class HashFun, class ExtractKey, class EqualKey, class Alloc=alloc>
class hashtable {
public:
		typedef HashFun hasher; // 散射函数
		typedef EqualKey key_equal; // 比较key值是否相等
		typedef size_t size_type;
private:
		// size = 1+1+1+12+4 = 19 -> 20
		hasher hash;  // 空函数对象:1
		key_equal equals;  // 空函数对象:1
		ExtractKey get_key;  // 空函数对象:1
		typedef _hashtable_node<Value> node;
		
		vector<node*, Alloc> buckets;  // vector中有三个指针:12
		size_type num_elements;  // 4
public:
		size_type bucket_count() const {return buckets.size();}

template <class Value>
struct __hashtable_node{
		__hashtable_node* next;  // 4
		Value val;  // 4
}

 

实际调用:

hashtable<const char*, const char*, hash<const char*>, identity<const char*>, eqstr, alloc> 
ht(50, hash<const chat*>(), eqstr());  // 50代表的是哈希表的初始桶(bucket)数量
ht.insert_unique("kiwi");

// 比较两个C语言风格的字符串是否相等,可以用strcmp()
// 但它返回的是-1,0,1,不是bool类型,因此需要加一层外套
// const char*表示指向字符串的指针,通过指针可以访问整个字符串
struct eqstr{
		bool operator()(const char* s1, const char* s2) const
		{return strcmp(s1,s2) == 0;}
};
  • C语言中的字符串是以'\\0'(空字符)结尾的字符数组。使用const char*表示指向字符数组的指针,而不是单个字符。如果你使用的是const char,那只表示一个字符,而不是一个字符串。
  • 比较两个字符串需要用指针遍历每个字符,因此要使用const char*
template<> 
struct hash<const char*>
{
		size_type operator()(const char* s) const
		{
				size_type hash = 0;
				while(*s)  // 遍历字符串中的每一个字符
				{
						hash = hash * 101 + *s++;  // 计算当前字符的ASCII值
				}
				return hash;
		}
};

5.unordered_set容器

unordered_set<string> c;
// 第i号篮子里有多少个元素
for(unsigned i=0; i<20; i++){
		cout << "bucket #" << i << c.bucket_size(i) << " elements.\\n";
}

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值