您的位置:首页 > 其它

链地址法实现一个很简单的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表

//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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: