哈希表(hashtable)
2016-04-08 17:24
239 查看
HashTable: 哈希表/散列表,是根据关键字(key)直接访问数据的数据结构。
它通过一个关键值的函数将所需的数据映射到表中的位置来访问数据,这个映射函数叫做散列函数,存放记录的数组叫做散列表。
构造哈希表的几种方法
1.直接定址法--取关键字的某个线性函数为散列地址,Hash(Key)= Key 或 Hash(Key)= A*Key + B,A、B为常数。
2.除留余数法--取关键值被某个不大于散列表长m的数p除后的所得的余数为散列地址。Hash(Key)= Key % P。
3.平方取中法
4.折叠法
5.随机数法
6.数学分析法
哈希冲突/哈希碰撞
不同的Key值经过哈希函数Hash(Key)处理以后可能产生相同的值哈希地址,我们称这种情况为哈希冲突。任意的散列函数都不能避免产生冲突。
处理哈希冲突的闭散列方法有:1.线性探测 2.二次探测
线性探测实现代码如下:
它通过一个关键值的函数将所需的数据映射到表中的位置来访问数据,这个映射函数叫做散列函数,存放记录的数组叫做散列表。
构造哈希表的几种方法
1.直接定址法--取关键字的某个线性函数为散列地址,Hash(Key)= Key 或 Hash(Key)= A*Key + B,A、B为常数。
2.除留余数法--取关键值被某个不大于散列表长m的数p除后的所得的余数为散列地址。Hash(Key)= Key % P。
3.平方取中法
4.折叠法
5.随机数法
6.数学分析法
哈希冲突/哈希碰撞
不同的Key值经过哈希函数Hash(Key)处理以后可能产生相同的值哈希地址,我们称这种情况为哈希冲突。任意的散列函数都不能避免产生冲突。
处理哈希冲突的闭散列方法有:1.线性探测 2.二次探测
线性探测实现代码如下:
#include <iostream> using namespace std; enum Status { EXIT, DELETE, EMPTY, }; template<class K> class HashTable { public: HashTable() :_table(NULL) , _size(0) , _cpacity(0) , _status(0) {} HashTable(size_t capacity) :_table(new K[capacity]) , _size(0) , _capacity(capacity) , _status(new Status[capacity]) { for (size_t i = 0; i < _capacity; i++) { _status[i] = EMPTY; } } ~HashTable() { if (_table) { delete[] _table; } if (_status) { delete[] _status; } } public: bool Insert(const K& x) { if ((_size * 10 / _capacity) > 8) { HashTable ht(_capacity * 2); int i = 0; Swap(ht); while (i < ht._capacity) { if (ht._status[i] == EXIT) { Insert(ht._table[i]); } i++; } } int index = HashFunc(x); while (_status[index] == EXIT) { index++; if (index == _capacity) { index = 0; } } _table[index] = x; _status[index] = EXIT; _size++; return true; } bool Remove(const K& x) { int index = HashFunc(x); while (_status[index] != EMPTY) { if (_table[index] == x) { _status[index] = DELETE; return true; } index++; if (index == _capacity) { index = 0; } } return false; } bool Find(const K& x) { int index = HashFunc(x); while (_status[index] != EMPTY) { if (_table[index] == x) { return true; } index++; if (index == _capacity) { index = 0; } } return false; } void Print() { for (size_t i = 0; i < _capacity; ++i) { cout << _status[i] << ":"; cout << _table[i] << " "; } cout << endl; } protected: void Swap(HashTable<int>& ht) { swap(_table, ht._table); swap(_status, ht._status); swap(_size, ht._size); swap(_capacity, ht._capacity); } size_t HashFunc(const K& x) { return (x % _capacity); } private: K* _table; size_t _size; size_t _capacity; Status* _status; }; int main() { HashTable<int> ht1(10); ht1.Insert(89); ht1.Insert(18); ht1.Insert(49); ht1.Insert(58); ht1.Insert(9); ht1.Insert(55); ht1.Insert(34); ht1.Insert(44); ht1.Insert(99); ht1.Insert(22); ht1.Print(); ht1.Remove(49); ht1.Print(); ht1.Find(58); return 0; }
相关文章推荐
- 5.4用形态学滤波器检测边缘和角点
- linux图形界面命令行切换
- 【学习笔记----数据结构04-单循环链表】
- 84.#define #if #ifdef #ifndef 作用和区别
- 教你透彻了解红黑树
- 由RGB到HSV颜色空间的理解
- 对美国某核武器研究项目站点的一次渗透测试 2013-09-19 12:59
- java List 排序 Collections.sort() 对 List 排序
- RN(react native)入坑指南-03,运行官方示例UIExplorer
- xcoj 1227 电梯
- Servlet 中文乱码问题及解决方案剖析
- VTK显示中文
- 实际用户和有效用户的
- 引入cocoaPods后找不到头文件,实际头文件就包含在Pods下
- linux开机默认进入命令界面
- HTTP缓存原理介绍
- 正则表达式详解以及用正则判断数值
- java第四次作业
- mysql 5.7 安装手册(for linux)
- [Android Studio] Android Studio常用快捷键