hashtables之哈希桶法
来源:互联网 发布:怎么查看服务器端口 编辑:程序博客网 时间:2024/05/19 15:43
#pragma once#include<iostream>#include<vector>#include<string>using namespace std;template<class K,class V>struct HashTablesNode{ K _key; V _value; struct HashTablesNode* next; HashTablesNode(const K& key, const V& value) : _key(key) , _value(value) , next(NULL) {}};static size_t BKDRHash(const char * str){ unsigned int seed = 131; // 31 131 1313 13131 131313 unsigned int hash = 0; while (*str) { hash = hash * seed + (*str++); } return (hash & 0x7FFFFFFF);}//为string定制的仿函数struct __HashFuncS{ size_t operator()(const string& str) { return BKDRHash(str.c_str()); }};//对 int型struct __HashFuncInt{ size_t operator()(const int& key) { return key; }};template<class K, class V, class H = __HashFuncInt >class HashTables{ typedef HashTablesNode<K,V> Node;public: HashTables() {} HashTables(size_t _size) { _table.resize(GetNextCapacity(size)); } void print() { for (size_t i = 0; i < _table.size();++i) { printf("_hashtable[%d]->", i); Node* pcur = _table[i]; while (pcur) { cout << pcur->_key << " :"<<pcur->_value<<" "; pcur = pcur->next; } cout << endl; } } bool Find(const K& key) { int index = _HashFunc(key,_table.size()); Node* pcur = _table[index]; while (pcur) { if (pcur->_key == key) return true; pcur = pcur->next; } return false; } bool Insert(const K& key, const V& value) { CheckCapacity(); if (Find(key)) return false; int index = _HashFunc(key,_table.size()); Node* tmp = new Node(key, value); tmp->next = _table[index]; _table[index] = tmp; size++; return true; } bool Remove(const K& key) { size_t index = _HashFunc(key, _table.size()); Node* pcur = _table[index]; if (pcur->_key == key) _table[index] = pcur->next; else { while (pcur) { Node* prev = pcur; pcur = pcur->next; if (pcur->_key == key) { prev->next = pcur->next; } } if (pcur == NULL) return false; } delete pcur; size--; return true; }private: size_t GetNextCapacity(size_t size) { const int _PrimeSize = 28; static const unsigned long _PrimeList[_PrimeSize] = { 53ul, 97ul, 193ul, 389ul, 769ul, 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, 1610612741ul, 3221225473ul, 4294967291ul }; for (size_t i = 0; i < _PrimeSize; ++i) { if (size < _PrimeList[i]) return _PrimeList[i]; } return _PrimeList[_PrimeSize]; } size_t _HashFunc(const K& key, size_t size)//除留余数法 { return H()(key) % size; } void CheckCapacity() { if (size == _table.size())//负载因子达到1.0 { //_table.resize(size * 2 + 3); vector<Node*> newtable; newtable.resize(GetNextCapacity(size)); for (size_t i = 0; i < _table.size(); ++i) { Node* pcur = _table[i]; while (pcur) { Node* pnext = pcur->next; // int index = _HashFunc(pcur->_key, newtable.size()); pcur->next = newtable[index]; newtable[index] = pcur; _table[i] = pnext; pcur = _table[i]; } } swap(newtable, _table); } }private: vector<Node*> _table; size_t size;};
用了素数表来配合除留余数法来减少冲突,用了哈希桶来处理哈希碰撞;
哈希表每个元素都是一个指针,指向一个单链表的第一个节点。插入数据就是往对应的key下面挂节点,查找的时候直接定位到对应的哈希表的位置,然后遍历单链表查找。对于这个单链表也可以其他方式来组织,如红黑树,让哈希表里面保存红黑树的根节点指针即可;
哈希桶的做法,相对于二次探测和线性探测,减少了前面数据对本次插入数据的影响。时间复杂度实际上通过优化可以达到0(1);缺点是比较浪费空间;
0 0
- hashtables之哈希桶法
- Hashtables
- Java Hashtables
- Java中的Hashtables
- java中的hashtables
- java的Hashtables
- Hashtables(哈希表)
- 运用Hashtables--Java
- 哈希表hashtables算法
- 在Java中运用Hashtables
- 在Java中运用Hashtables
- 在Java中运用Hashtables
- 在Java中运用Hashtables
- 在Java中运用Hashtables
- 在Java中运用Hashtables
- HashTables - Concepts, Theory , Questions - Codophilic:
- 23-翻译一篇HashTables文章
- Data.Structures.For.Game.Programmers.PART2.Basics.8.HashTables
- pom.xml中的java.home变量(eclipse默认的java.home变量)&& pom.xml详解&&maven常用配置的变量
- 【2016】八月份英语学习总结
- 高速乘车
- 深度解析oracle的rownum
- UVa OJ 12627 - Erratic Expansion
- hashtables之哈希桶法
- python常见HTTPError异常
- 记录mysql中的DATE_FORMAT()函数的使用
- 前端开发中的部分兼容性问题
- LeetCode第一题
- <Pro ASP.NET MVC 5> - Note01
- DVB-SI理解入门指南(一)(二)(三)
- 微信公众号开发---微信支付(JS API) JAVA
- JUnit4 执行测试时报initializationError错误