哈希冲突之开链法
2016-03-17 15:09
429 查看
哈希碰撞/哈希冲突:不同的Key值经过哈希函数Hash(Key)处理以后可能产生相同的值哈希地址,我们称这种情况为哈希冲突。
#include<iostream> #include<vector> #include<string> using namespace std; template<class K,class V> struct Node { K _key; V _value; Node*_next; Node(const K& key, const V& value) :_key(key) , _value(value) , _next(NULL) {} }; template<class T> struct Hasher { size_t operator() (const T& key) { return key; } }; template<> struct Hasher<string> { size_t operator() (const string& s) { const char* str = s.c_str(); unsigned int seed = 131; // 31 131 1313 13131 131313 unsigned int hash = 0; while (*str) { hash = hash * seed + (*str++); } return (hash & 0x7FFFFFFF); } }; 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 }; template<class K, class V, class HashFunc = Hasher<K>> class HashTable { public: HashTable(size_t capacity) { _size = 0; _table.reserve(capacity); _table.assign(capacity, NULL); } void Insert(const K& key, const V& value)//放入数据 { ExpandCapacity(); int pos = _HashFunc(key, _table.size()); Node<K,V>*begin = _table[pos]; while (begin != NULL) { if (begin->_key == key) { return; } begin = begin->_next; } Node<K,V>*tmp = new Node<K,V>(key, value); tmp->_next = _table[pos]; _table[pos] = tmp; ++_size; } void Delete(const int&key)//删除结点 { size_t pos = (size_t)key % (size_t)_table.capacity(); Node*begin = _table[pos]; Node*prev = NULL; while (begin) { if (begin->_key == key) { if (begin == _table[pos]) { _table[pos] = _table[pos]->_next; } else { prev->_next = begin->_next; } delete begin; return; } prev = begin; begin = begin->_next; } } void Print() { for (int i = 24; i <(int) _table.capacity(); i++) { Node<K,V>*begin = _table[i]; while (begin != NULL) { printf("pos[%d]:", i); cout << "(" << begin->_key <<","<< begin->_value<<")"; cout << "->"; begin = begin->_next; } cout <<"NULL"<< endl; } } protected: void ExpandCapacity()//实现扩容 { if (_size >= (size_t)_table.capacity()) { int NewCapacity = CapacityNum(_size); vector<Node<K,V> *>tmp; tmp.reserve(NewCapacity); tmp.assign(NewCapacity, NULL); for (size_t i = 0; i < (size_t)_table.capacity(); i++) { while (_table[i] != NULL) { //摘节点 Node<K,V>* head = _table[i]; _table[i] = _table[i]->_next; //放节点 int pos = _HashFunc((head->_key),NewCapacity); head->_next = tmp[pos]; tmp[pos] = head; } } _table.swap(tmp); } } size_t CapacityNum(size_t num) //得到应该扩展到的容量值 { for (int i = 0; i < _PrimeSize; i++) { if (_PrimeList[i]>num) { return _PrimeList[i]; } } return _PrimeList[_PrimeSize - 1]; } int _HashFunc(const K& key, size_t capacity) { HashFunc hashFunc; // operator() return hashFunc(key) % _table.capacity(); } private: vector<Node<K,V>*>_table; size_t _size; };
相关文章推荐
- 当spring 容器初始化完成后执行某个方法
- Java中的集合
- TOMCAT JDBC连接不上MYSQL的常用诊断
- ios 中生成随机数
- 长按事件jquery mobile
- IOS异步获取数据并刷新界面dispatch_async的使用方法
- Spark机器学习读书笔记
- Spring 源码分析(三) —— AOP(六)源码分析与总结
- C++中STL与MFC的关系
- Oracle表空间、段、区和块简述
- 移动端H5页面高清多屏适配方案
- SQLite数据库的锁机制
- 【小镇的技术天梯】Fast-CGI和php-fpm之间的关系
- 【leetcode】Wildcard Matching
- Junit应用代码(读取mysql表数据)
- javascript权威指南学习笔记3
- 移动端禁止滚动条恢复滚动条
- Java 基础高级2 网络编程
- A星算法(游戏寻路算法)的C++实现(转)
- mysql索引问题