哈希容器

目录

  • hashtable

    • 开链法

      • hashtable的桶子(buckets)与节点(nodes)
      • haah table的图示
    • hashtable实现
      • hashtable的节点实现
      • hashtable的迭代器实现
    • hashfunction的设计
  • unordered_set

hashtable

将一系列数放入容器中,将数除以内存的大小M,得到的余数挂在每个篮子下面。篮子的个数M一般取质数,当篮子所挂的链表长度大于篮子个数M时,就要rehashing,扩充篮子的数量(vector二倍扩充,不过扩充以后选取2*M附近的质数)

开链法

hashtable的桶子(buckets)与节点(nodes)

hash table表格内的元素为桶子(bucket),此名称的大约意义是:表格内的每个单元,涵盖的不只是个节点(元素),甚至可能是一桶节点。

haah table的图示


buckets vector大小为任意常数,虽然list是线性搜寻时间,如果list够小,搜寻速度仍然很快。

GC编译器将bucket的个数设置为53,当桶中元素的个数大于bucket的个数时,就需要对放置桶的vector进行扩容,我们可以使用hashtable iterators改变元素的data,但不能改变元素的key.

hashtable实现

  • HashFcn : 是hash函数
  • ExtractKey: 插入的元素是一包东西,可能是一个pair,必须要告诉如何取出这个key
  • EqualKey: 如何对key进行判等
template <class Value, class Key, class HashFcn,
          class ExtractKey, class EqualKey,
          class Alloc = alloc>
    class hashtable {
    public:
        typedef HashFcn  hasher; //hash函数
        typedef EqualKey key_equal; //判等函数
        typedef size_t size_type;
    private:
        hasher hash; //大小为0,但是实际值为1
        key_equal equals;//大小为0,但是实际值为1
        ExtractKey get_key;//大小为0,但是实际值为1
        typedef __hashtable_node<Value>node;
        vector<node*, Alloc>buckets; // vector里有三个指针,大小为12
        size_type num_elements;//4个字节
    public:
        size_type bucket_count() const { return bucket.size(); }
};
  • hashtable总共大小是19个字节,调整为4的倍数,一共是20个字节。

hashtable的节点实现

其中node节点的设置如下:

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

除了需要保存数据本身之外,还需要一个指针去指向下一个元素。

hashtable的迭代器实现

struct __hashtable_iterator {
    node* cur;
    hashtable* ht;
};

hashfunction的设计

hashfunction的目的是:希望能够根据元素的值计算出一个hashcode,使得元素经过hash code映射之后,能够被随机的放置于hashtable中,越是够乱,越不容易产生碰撞。

unordered_set

原文地址:https://www.cnblogs.com/ccpang/p/12284018.html

时间: 2024-08-01 15:39:05

哈希容器的相关文章

哈希容器的使用

stl的容器库非常强大,但是为了要兼容各种元素类型,采用了模板进行泛化,这样的好处就是使用非常的方便,但是编译器会对使用到的每种类型都进行一遍实例化,用的类型太多的话不仅影响编译速度而且生成的可执行文件也很冗余. 因此,TBOX在设计容器架构的时候,引入tb_item_func_t类型,来设置容器使用的成员类型,这样在实现容器通用性的同时,也不会产生过的冗余,而且容器接口操作上,同样相当的便利. 可以先看个简单使用哈希的例子: /* 初始化hash, 哈希桶大小8 * 键:大小写敏感字符串 *

Effective STL 条款1:仔细选择你的容器

条款1:仔细选择你的容器 了解各种容器的实现方法,知道各种容器的内存管理方式.各种操作所对应的底层操作,然后根据需要选择恰当的容器. 对于容器的分类: 标准STL序列容器:vector,string,deque和list 标准STL关联容器:set,multiset,map和multimap 非标准序列容器:slist(单向链表)和rope(重型字符串--不懂) 非标准关联容器:hash_set,hash_multiset,hush_map和hash_multimap vector == str

C++ 容器一些细节

参考:http://www.cnblogs.com/answeryi/archive/2011/12/16/2289811.html: 目录 ==================================================== 第一章 容器 第二章 Vector和string 第三章 关联容器 第四章 迭代器 第五章 算法 第六章 函数 第七章 在程序中使用STL ==================================================== 第1章

哈希表-统计字符出现的次数

第一个只出现一次的字符:在字符串中找出第一个只出现一次的字符.如输入“abaccdeff”则输出b 答案:由于题目出现了与字符出现次数相关.我们可以利用一个容器来存放每个字符出现的次数,也就是说这个容器的作用是把一个字符隐射成一个数字.所以我们利用哈希表. #include <QCoreApplication> #include<iostream> #include<QDebug> char findOnlyOneChar(char *inputString) { if

c++容器使用总结(转载)

目录 ==================================================== 第一章 容器 第二章 Vector和string 第三章 关联容器 第四章 迭代器 第五章 算法 第六章 函数 第七章 在程序中使用STL ==================================================== 第1章 容器 第1条:慎重选择容器类型. 标准STL序列容器:vector.string.deque和list. 标准STL关联容器:set.

C++ 容器及选用总结(转载供自学)

C++ 容器及选用总结 目录 ==================================================== 第一章 容器 第二章 Vector和string 第三章 关联容器 第四章 迭代器 第五章 算法 第六章 函数 第七章 在程序中使用STL ==================================================== 第1章 容器 第1条:慎重选择容器类型. 标准STL序列容器:vector.string.deque和list. 标准

C++ 容器及选用总结

第1章 容器 第1条:慎重选择容器类型. 标准STL序列容器:vector.string.deque和list. 标准STL关联容器:set.multiset.map和multimap. 非标准序列容器slist和rope.slist是一个单向链表,rope本质上是一"重型"string. 非标准的关联容器hash_set.hase_multiset.hash_map和hash_multimap. vector<char> 作为string的替代.(见第13条) vecto

C++容器

第1章 容器 第1条:慎重选择容器类型. 标准STL序列容器:vector.string.deque和list. 标准STL关联容器:set.multiset.map和multimap. 非标准序列容器slist和rope.slist是一个单向链表,rope本质上是一"重型"string. 非标准的关联容器hash_set.hase_multiset.hash_map和hash_multimap. vector<char> 作为string的替代.(见第13条) vecto

读书笔记 effective c++ Item 47 使用traits class表示类型信息

STL主要由为容器,迭代器和算法创建的模板组成,但是也有一些功能模板.其中之一叫做advance.Advance将一个指定的迭代器移动指定的距离: 1 template<typename IterT, typename DistT> // move iter d units 2 void advance(IterT& iter, DistT d); // forward; if d < 0, 3 // move iter backward 从概念上来说,advance仅仅做了it