STL源码分析 unordered_set容器

源代码来自sgi-2.91版本stl_hash_set.h

unordered_set总述

先了解hash表

(1)底层实现完全由hash表代替,最开始叫做hash_set,从实现原理来说unordered_set应该被称为容器适配器

(2)对底层hash表来说,键值就是实值

(3)hash表没有自动排序,所以相对于set,unordered_set没有自动排序

(4)unordered_set适合用于只查找元素的情况

unordered_set类

#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class Value, class HashFcn = hash<Value>,		//hash函数来对元素编号
          class EqualKey = equal_to<Value>,			//比较==函数
          class Alloc = alloc>		//allco分配器
#else
template <class Value, class HashFcn, class EqualKey, class Alloc = alloc>		//自定义参数
#endif
class hash_set
{
private:
  typedef hashtable<Value, Value, HashFcn, identity<Value>, 
                    EqualKey, Alloc> ht;	//申明hash表
  ht rep;		//创建hash表

public:
  typedef typename ht::key_type key_type;
  typedef typename ht::value_type value_type;
  typedef typename ht::hasher hasher;
  typedef typename ht::key_equal key_equal;

  typedef typename ht::size_type size_type;
  typedef typename ht::difference_type difference_type;
  typedef typename ht::const_pointer pointer;
  typedef typename ht::const_pointer const_pointer;
  typedef typename ht::const_reference reference;
  typedef typename ht::const_reference const_reference;

  typedef typename ht::const_iterator iterator;		//注意此处,默认const_iterator 
  typedef typename ht::const_iterator const_iterator;

  hasher hash_funct() const { return rep.hash_funct(); }
  key_equal key_eq() const { return rep.key_eq(); }

hash_set默认构造

hash_set() : rep(100, hasher(), key_equal()) {}		//默认构造,hash表中找到比100大的质数193作为buckets容量

  explicit hash_set(size_type n) : rep(n, hasher(), key_equal()) {}
  hash_set(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
  hash_set(size_type n, const hasher& hf, const key_equal& eql)
    : rep(n, hf, eql) {}

size()

size_type size() const { return rep.size(); }

调用hash表的size

size_type size() const { return num_elements; }		//返回元素个数,num_elements会随着插入删除变化

begin()、end()

iterator begin() const { return rep.begin(); }
  iterator end() const { return rep.end(); }

find()

iterator find(const key_type& key) const { return rep.find(key); }		//调用hash表find函数

在hash表中找元素,根据键值查找

iterator find(const key_type& key) 
  {
    size_type n = bkt_num_key(key);		//找到在buckets中落脚点
    node* first;
    for ( first = buckets[n];
          first && !equals(get_key(first->val), key);		//键值相等或first指向null时返回
          first = first->next)
      {}
    return iterator(first, this);		//返回一个迭代器
  } 

count()

统计有多少元素

size_type count(const key_type& key) const { return rep.count(key); }

insert()

pair<iterator, bool> insert(const value_type& obj)
    {
      pair<typename ht::iterator, bool> p = rep.insert_unique(obj);		//在hash表的插入中会判断有没有重复元素
      return pair<iterator, bool>(p.first, p.second);		//first是迭代器,second代表是否成功插入
    }

erase()

删除元素

size_type erase(const key_type& key) {return rep.erase(key); }
  void erase(iterator it) { rep.erase(it); }

测试函数

#include<ostream>
#include<unordered_set>
using namespace std;
int main()
{
	unordered_set<int> se;
	unordered_set<int>::iterator it;
	int val = 100;
	for (int i = 0; i < val; i++)
		se.insert(i);
	//se.insert(10);
	cout << *se.begin() << endl;
	for (unsigned i = 0; i < se.bucket_count(); ++i) {
		std::cout << "bucket #" << i << " contains:";
		for (auto local_it = se.begin(i); local_it != se.end(i); ++local_it)
			std::cout << " " << *local_it;
		std::cout << std::endl;
	}

}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值