链地址法实现一个很简单的hash表
2010-07-25 14:27
302 查看
链地址法实现一个很简单的hash表
[1]hash函数定义
根据key,计算出key对应记录的储存位置
position = f(key)
函数f就是hash函数
[2]hash冲突定义
不同的key可能得到相同的position。原因为key值的范围过大。如int.
如果构造一个完全没有冲突的表。那么对应的地址空间就是4G,这是根本不
实现的。为了处理这个问题。就允许不同的key可以有相同的position。
[3]hash表定义
映射的集合
[4]设计一个好的hash函数非常重要
由[2]可知,一个好的hash函数可以使positions集中分布在某一段内存地址范围内。
并且position在这段地址范围内存尽量均匀。这样每个key对应的position就尽可能
少了,即hash冲突少。查找就会快一点。
[5]所谓的hash桶定义
就是预分配的一段连续的储存空间
[6]处理冲突的方法
(1)开放定址法:就是先指定一个桶,然后position = f(key,d),如果postion已经存在了,改变参数d,
继续计算position = f(key,d),直到postion不存在
d的不同取值的算法有:线性探测再散列,二次探测再散列,伪随机探测再散列。
听这名字觉得好高深哦。实际上, 就是为了更高效地计算出没有使用的position
(2)链地址法
就是把position相同的item按插入的先后顺序组成一个链表
现用链地址法实现一个很简单的hash表
[1]hash函数定义
根据key,计算出key对应记录的储存位置
position = f(key)
函数f就是hash函数
[2]hash冲突定义
不同的key可能得到相同的position。原因为key值的范围过大。如int.
如果构造一个完全没有冲突的表。那么对应的地址空间就是4G,这是根本不
实现的。为了处理这个问题。就允许不同的key可以有相同的position。
[3]hash表定义
映射的集合
[4]设计一个好的hash函数非常重要
由[2]可知,一个好的hash函数可以使positions集中分布在某一段内存地址范围内。
并且position在这段地址范围内存尽量均匀。这样每个key对应的position就尽可能
少了,即hash冲突少。查找就会快一点。
[5]所谓的hash桶定义
就是预分配的一段连续的储存空间
[6]处理冲突的方法
(1)开放定址法:就是先指定一个桶,然后position = f(key,d),如果postion已经存在了,改变参数d,
继续计算position = f(key,d),直到postion不存在
d的不同取值的算法有:线性探测再散列,二次探测再散列,伪随机探测再散列。
听这名字觉得好高深哦。实际上, 就是为了更高效地计算出没有使用的position
(2)链地址法
就是把position相同的item按插入的先后顺序组成一个链表
现用链地址法实现一个很简单的hash表
//HashTable.h #pragma once #include <string> using std::string; typedef unsigned int UINT; //链表地址法 class Node { public: Node(int key, const string & str); int key; string value; Node * next; }; class HashTable { public: HashTable(); //插入操作 //返回值:插入是否成功 bool Insert(int key, const string & value); //查询操作 //返回值:是否找到 bool Find(int key); //访问操作 string & operator[](int key); private: //插入操作 //返回值:插入是否成功 bool Insert(Node ** node, int key, const string & value); Node * HashTable::FindNode(int key); //哈希函数 unsigned int hasher(int key); enum{SIZE = 100}; Node * nodes[SIZE]; };
//HashTable.cpp #include "HashTable.h" #include <cmath> #include <cassert> #include <memory.h> Node::Node(int Key, const string & str) : key(Key), value(str), next(0) { } HashTable::HashTable() { memset(nodes, 0, SIZE * sizeof(Node *)); } unsigned int HashTable::hasher(int key) { //最简单的hash函数 return abs(key) % SIZE; } bool HashTable::Insert(int key, const std::string &value) { UINT adr = hasher(key); Node * node = nodes[adr]; if(node == 0) { nodes[adr] = new Node(key, value); } else { return Insert(&node->next, key, value); } } bool HashTable::Insert(Node * * next, int key, const string & value) { Node * node = *next; if(node == 0) { (*next) = new Node(key, value); return true; } else { return Insert(&node->next, key, value); } } bool HashTable::Find(int key) { UINT adr = hasher(key); Node * node = nodes[adr]; if(node == 0) { return false; } else { do { if(node->key == key) { return true; } else { node = node->next; } }while(node != 0); return false; } } Node * HashTable::FindNode(int key) { UINT adr = hasher(key); Node * node = nodes[adr]; if(node == 0) { return 0; } else { do { if(node->key == key) { return node; } else { node = node->next; } }while(node != 0); return 0; } } string & HashTable::operator[](int key) { Node * node = FindNode(key); assert(node != 0); return node->value; }
//main.cpp #include <iostream> #include <string> #include "HashTable.h" using namespace std; int main() { HashTable ht; ht.Insert(1, "you"); string value = ht[1]; cout << value << endl; ht.Insert(101, "girl"); value = ht[101]; cout << value << endl; ht.Insert(201, "boy"); value = ht[201]; cout << value << endl; ht[201] = "man"; cout << ht[201] << endl; cin.get(); return 0; }
相关文章推荐
- 一个二维码实现同时支持AppStore下载地址 、安卓端下载地址
- VC实现同一个IE中打开不同的地址
- 一个很简单的淘宝优惠券搜索助手 大家看看有没有用吧 下载地址:http://pan.baidu.com/s/1skRHTDF
- 一个很简单的demo来演示一个账号只能同时被一个人使用(Java实现)
- 如何让地址实现某一个长度的地址对齐?
- 一个很简单的办法实现TD的加亮效果.
- 最小/大堆算法的一个很简单的实现
- 算法导论10.2-8-用一个整数地址替代前后指针实现双向链表
- 一个很简单的无限分类树实现代码
- 大多数分布式存储系统要么实现一个分布式Hash表,要么实现分布式B+树
- 【hash表】两种实现(链地址法,开放地址法)
- 一个很简单的办法实现TD的加亮效果.
- java和jdom实现的一个地址簿源码
- 实现一个Memcpy函数:将源指针所指的区域从起始地址开始的n个字节复制到目的指针所指区域
- 一个ListView根据标识加载不同布局,很简单的例子,就是聊天界面,你说话在右边好友在左边怎么实现呢.
- 如何设计实现一个地址反解析服务?
- 一个很简单的JS实现的选项卡
- img的src不连接本地地址实现输出一个图片(使用base64)
- 一个二维码实现同时支持AppStore下载地址 、安卓端下载地址
- 实现一个简单的邮箱地址爬虫(python)