哈希表

哈希

哈希又名散列法,是一种特殊的查找方法

哈希法是希望不通过任何的比较,一次存取就能得到元素

一、设计哈希表

1.确定表的空间范围,确定哈希值域

2.构造一个合适的哈希函数,这个函数要确保表中的元素经过该函数的计算之后,函数的返回值的范围在哈希值域之内

3.选择处理冲突的方法(用链式结构)

二、哈希函数

定义好的哈希函数是哈希表设计的关键

1.自身函数

2.数字分析法(数字叠加法,数字求余法等)

三、哈希示例

#include<iostream>
using namespace std;


struct mynode//链式结构(处理冲突)
{
	int data;
	mynode *pnext;
};

struct hashtable
{
	
	mynode* val[10];//定义一个指针数组,里面每一个元素都是一个指针,指向一个链表,可以理解为每一个链表的头指针
};

hashtable* createhashtable()//创建一个哈希表
{
	hashtable* phash = new hashtable;//new了40个字节大小的内存
	memset(phash, 0, sizeof(hashtable));//将phash全部赋0
	return phash;
}

bool inserthashtable(hashtable* phash, int data)//插入数据
{
	if (phash == nullptr)//哈希表不存在就直接退出不用插入数据
		return false;

	//申请一个节点来保存要插入的数据,就是内部数据内部管理
	mynode* pnode = new mynode;
	pnode->data = data;
	pnode->pnext = nullptr;//内部数据内部管理

	if (phash->val[data % 10] == nullptr)//如果链表不存在
		phash->val[data % 10] = pnode;
	else
	{
		//如果链表存在
		//用ptemp这个指针去指向链表头指针,方便接下来的操作
		mynode* ptemp = phash->val[data % 10];
		while (ptemp->pnext)
		{
			ptemp = ptemp->pnext;
		}
		ptemp->pnext = pnode;
	}
	return true;

}

//查找数据
mynode* finddatahash(hashtable* phash, int findata)
{
	if (phash == nullptr)//哈希表为空,直接退出
		return nullptr;

	//先找到你要查找的链表
	mynode* pnode = phash->val[findata % 10];
	if (pnode == nullptr)
		return nullptr;
	while (pnode)
	{
		if (pnode->data == findata)
			return pnode;
		pnode = pnode->pnext;
	}
	return nullptr;
}

//删除数据
bool deletedatahash(hashtable* phash, int deldata)
{
	//用一个节点来接收,查找到的节点
	mynode* pnode = finddatahash(phash, deldata);
	if (pnode == nullptr)
		return false;

	//接收链表头
	mynode* ptemphead = phash->val[deldata % 10];
	if (ptemphead == pnode)
	{
		//如果要删除的节点就是链表的头节点,那么直接让原来的头指针指向头节点之后的那一个节点
		phash->val[deldata % 10] = pnode->pnext;
	}
	else
	{
		while (ptemphead->pnext != pnode)
		{
			ptemphead = ptemphead->pnext;
		}
		//相当于是pnode=pnode->pnext;
		ptemphead->pnext = pnode -> pnext;
	}
	delete pnode;
	return true;
}
void clearhashtabl(hashtable*&phash)
{
	if (phash == nullptr)
		return;

	mynode* phead = nullptr;
	mynode* pcurrent = nullptr;
	for (int i = 0; i < 10; i++)
	{
		if ((phead = phash->val[i]) != nullptr)
		{
			while (phead)
			{
				pcurrent = phead;
				phead = phead->pnext;
				delete pcurrent;
			}
		}
	}
	delete[]phash;
	phash = nullptr;//如果这里不用引用,那么就不能赋空值,因为赋空值只是给phash这个形参赋的,没有影响到实参phash
}

int main()
{
	hashtable* phash = nullptr;
	phash = createhashtable();//在堆区创建哈希表的内存空间
	inserthashtable(phash, 1);
	inserthashtable(phash, 21);
	inserthashtable(phash, 31);
	inserthashtable(phash, 41);
	deletedatahash(phash, 1);
	clearhashtabl(phash);
	return 0;
}
posted @ 2021-04-09 16:58  kisfly  阅读(53)  评论(0编辑  收藏  举报