哈希表的实现

相关定义:根据散列函数H(key)和处理冲突的方法将一组关键字映象到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“象” 作为记录在表中的存储位置,这种表便称为散列表(或称哈希表),这一映象过程称为散列造表或散列,所得的存储位置称散列地址

构造哈希函数的方法: 

1. 直接寻址法;2. 数字分析法;3. 平方取中法; 

4. 折叠法;5. 随机数法;6. 除留余数法

处理冲突的方法

1. 开放寻址法:Hi=(H(key) + di) MOD m,i=1,2,…,k(k<=m-1),其中H(key)为散列函数,m为散列表长,di为

    增量序列,可有下列三种取法:  

     1.1. di=1,2,3,…,m-1,称线性探测再散列; 

     1.2. di=1^2,-1^2,2^2,-2^2,⑶^2,…,±(k)^2,(k<=m/2)称二次探测再散列; 

     1.3. di=伪随机数序列,称伪随机探测再散列。  

2. 再散列法:Hi=RHi(key),i=1,2,…,k RHi均是不同的散列函数,即在同义词产生地址冲突时计算另一个散列函数地址,直到冲突不再发生,这种方法不易产生“聚集”,但增加了计算时间。  

3. 链地址法  

4. 建立一个公共溢出区


代码:

// HashTable.cpp : 定义控制台应用程序的入口点。
//哈希表的实现
//哈希函数采用除留余数法构造
//使用链地址法解决冲突

#include "stdafx.h"
#include <iostream>
using namespace std;

const int MAXSIZE = 100; 
int a[MAXSIZE];

//哈希表的结点类型
class HashNode
{
public:
	HashNode():next(NULL){};//默认构造函数
	HashNode(int item):data(item), next(NULL){};//一般构造函数

private:
	int data;
	HashNode *next;
	friend class HashTable;
};

//哈希表类型
class HashTable
{
public:
	HashTable();
	void Create(int *a, int n);//创建哈希表
	bool Find(int data);//查找
	void Insert(int data);//插入
	void Delete(int data);//删除

private:	
	HashNode *value[10];//哈希表长度为10
};

HashTable::HashTable()//默认构造函数
{	
	memset(value, NULL, 10*sizeof(HashNode*));
}

void HashTable::Create(int *a, int n)
{
	cout << "请输入n个元素:" << endl;
	for (int i=0; i<n; i++)
	{
		cin >> a[i];
		Insert(a[i]);
	}
}

bool HashTable::Find(int data)
{
	HashNode *pNode = NULL;

	if (value[data%10] == NULL)//该结点不存在,则返回false
	{		
		return false;
	}

	pNode = value[data%10];//获取所在位置对应的链表的第一个结点
	while(pNode ->next != NULL && pNode->data != data)
	{
		pNode = pNode->next;
	}

	if (pNode != NULL)
	{		
		return true;
	}
	else 
	{        
		return false;
	}
}

void HashTable::Insert(int data)
{
	HashNode *pNode = NULL;

	if (value[data%10] == NULL)//获取所在位置对应的链表为空,则插入
	{
		pNode = new HashNode;
		pNode->data = data;
		value[data%10] = pNode;
	}
	else//所在位置对应的链表不空
	{
		if (Find(data))//检查该数值是否已经存在,若存在则返回
		{
			return;
		}
		else//否则插入链表尾端
		{
			pNode = value[data%10];
			while(pNode->next != NULL)
			{
				pNode = pNode->next;
			}

			HashNode *newNode = new HashNode(data);				
			pNode->next = newNode;
		}		
	}
}

void HashTable::Delete(int data)
{
	HashNode *pNode = NULL;//定位到待删除的结点
	HashNode *pPre = NULL;//定位到待删除结点的前一个结点	

	if (!Find(data))
	{
		cout << "该数值的结点不存在!" << endl;
	}
	else
	{
		pNode = value[data%10];//初始值为所在位置对应的链表的第一个结点		
		if(pNode->data == data)//头结点即为待删除的结点
		{
			value[data%10] = pNode->next;
			cout << data << "删除成功!" << endl;
		}
		else//否则指针后移,找到待删除的结点
		{	
			pPre = pNode;
			while(pNode->next != NULL && pNode->next->data != data)
			{
				pPre = pNode;
				pNode = pNode->next;				
			}
			pPre->next = pNode->next;
			delete pNode;
			pNode = NULL;
			cout << data << "删除成功!" << endl;
		}	
	}	
}

int _tmain(int argc, _TCHAR* argv[])
{	
	int n = 0;
	cout << "请输入哈希表元素的个数:";
	cin >> n;
	
	HashTable *ht = new HashTable;
    ht->Create(a, n);	

	cout << ht->Find(9) << endl;
	cout << ht->Find(3) << endl;

	ht->Delete(10);
	ht->Delete(8);

	cout << ht->Find(8) << endl;

	system("pause");
	return 0;
}







你可能感兴趣的:(null,delete,存储,Class,insert)