哈希
哈希又名散列法,是一种特殊的查找方法
哈希法是希望不通过任何的比较,一次存取就能得到元素
一、设计哈希表
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;
}