哈希
什么是哈希:
哈希:hash;就是散列函数
1 哈希冲突的4种处理方法:
- 1.开放定址法:也叫线性探测法;
一次探测缺点就是数据会集中在一块,解决方法就是平方探测(二次探测),避免堆积
正数:代表向右探测
负数:代表向左探测
-
2.再散列函数(哈希)法:
-
3.链地址法:
只要数据有冲突就头插在同一个下标下 -
公共溢出区法:
一个基本表,一个溢出表;将有冲突的数据放入溢出表。
缺点是当数据过大,基本表太小时,溢出表的规格将会很大
2 链式哈希
结构定义:
#define HASHSIZE 12
typedef struct Node
{
int data;
struct Node* next;
}Node, * PNode;
typedef struct Head
{
//struct Node *arr[HASHSIZE];//指针数组(存放指针的数组)
struct Node arr[HASHSIZE];//数组arr中存放Node本身
}Head, * PHead;
API实现
void Init_listhash(PHead ph)
{
//assert
for (int i = 0; i < HASHSIZE; i++)
{
//ph->arr[i].data;// 不使用
ph->arr[i].next = NULL;
}
}
bool Insert_hash(PHead ph, int key)//头插
{
int hash = key % HASHSIZE;
//创建新节点
struct Node* pnewnode = (Node*)malloc(sizeof(Node) * 1);
assert(pnewnode != NULL);
pnewnode->data = key;
//插入
pnewnode->next = ph->arr[hash].next;
ph->arr[hash].next = pnewnode;
return true;
}
bool Del_Hash(PHead ph, int key)
{
int hash = key % HASHSIZE;
struct Node* p = &ph->arr[hash];
for (p; p->next != NULL; p = p->next)
{
if (p->next->data == key)
{
//此时p->next 指向的这个节点就是我们要删除的那个节点
struct Node* q = p->next;
p->next = q->next;
free(q);
q = NULL;
return true;
}
}
return false;
}
struct Node* Search(PHead ph, int key)
{
int hash = key % HASHSIZE;
struct Node* p = ph->arr[hash].next;
for (p; p != NULL; p = p->next)
{
if (p->data == key)
{
return p;
}
}
return NULL;
}
void Show_Hash(PHead ph)
{
for (int i = 0; i < HASHSIZE; i++)
{
printf("%3d: ", i);
struct Node* p = ph->arr[i].next;
for (p; p != NULL; p = p->next)
{
printf("%d ", p->data);
}
printf("\n");
}
}