哈希(hash)
作者:互联网
1、哈希 Hash(散列):
哈希函数等于散列函数,哈希是一种存储方法,还是一种排序方法,只要算法中用到哈希思想,就可以叫hash算法。
将数据自身的值和最终的存储位置形成一个特定关系 这个关系叫做hash函数:ex:y(存储位置)=f(x(关键值key))
顺序表:节点之间,物理相邻,逻辑也相邻
链表:节点之间,物理可能不相邻,逻辑相邻
哈希表:节点之间,节点地址与被存储数据之间存在逻辑关系。
2、如何构造哈希(6种)
3、如何解决哈希冲突(主要是连地址法)
1、开放地址法
2、再散列函数法
3、链地址法
1、结构体设计
无论有多少个冲突,都只是在当前位置给单链表增加节点的问题。
根据上面的例子,结构体设计:用散列地址作为头节点,将后面的冲突节点链在后面。
typedef int ELEM_TYPE;
#define List_hash_SIZE 12
typedef struct Node
{
int data;//数据
struct Node* next;//指针域
}node,*Pnode;
typedef struct Head
{
struct Node* arr[List_hash_SIZE];
}head,*Phead;
2、头文件
#pragma once
typedef int ELEM_TYPE;
#define List_hash_SIZE 12
typedef struct Node
{
int data;//数据
struct Node* next;//指针域
}node,*Pnode;
typedef struct Head
{
struct Node* arr[List_hash_SIZE];
}head,*Phead;
//购买节点
Pnode Buynode();
//添加
bool Insert_key(Phead ph, ELEM_TYPE key);
//删除
bool Del_key(Phead ph, ELEM_TYPE key);
//查找
struct Node* Search(Phead ph, ELEM_TYPE key);
//打印
void Print(Phead ph);
//判空
bool Is_Empty(Phead hp);
3、主函数
#include"List_hash.h"
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
//购买节点
Pnode Buynode()
{
Pnode s = (Pnode)malloc(sizeof(Node));
if (s == NULL)
{
return NULL;
}
return s;
}
//初始化
void Init_hash(Phead ph)
{
assert(ph != NULL);
for (int i = 0; i < List_hash_SIZE; i++)
{
ph->arr[i] = NULL;//给key的散列地址赋值
}
return;
}
//添加
bool Insert_key(Phead ph, ELEM_TYPE key)
{
assert(ph != NULL);//断言存在
int index = key % List_hash_SIZE;//找到散列地址下标
//申请节点
Pnode s = Buynode();
s->data = key;
// 插入 头插
s->next=ph->arr[index];
ph->arr[index] = s;
return true;
}
//删除
bool Del_key(Phead ph, ELEM_TYPE key)
{
assert(ph != NULL);//断言存在
int index = key % List_hash_SIZE;
struct Node* p = ph->arr[index];
while (p != NULL)
{
if (p->next == NULL)
{
if (p->data == key)
{
ph->arr[index] = NULL;
return true;
}
}
else
{
if (p->next->data == key)
{
Pnode q = p->next;
p->next = q->next;
free(q);
q = NULL;
}
if (p->data == key)
{
ph->arr[index] = ph->arr[index]->next;
}
return true;
}
p = p->next;
}
return false;
}
//查找
struct Node* Search(Phead ph, ELEM_TYPE key)
{
assert(ph != NULL);//断言存在
if (Is_Empty(ph))
{
return NULL;
}
int index = key % List_hash_SIZE;
Pnode p = ph->arr[index];
while (p != NULL)
{
if (p->data == key)
{
return p;
}
p = p->next;
}
return NULL;
}
//打印
void Print(Phead ph)
{
assert(ph != NULL);//断言存在
for (int i = 0; i < List_hash_SIZE; i++)
{
printf("%-2d:",i);
Pnode p = ph->arr[i];
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
}
//判空
bool Is_Empty(Phead hp)
{
assert(hp != NULL);
for (int i = 0; i < List_hash_SIZE;i++)
{
if (hp->arr[i] != NULL)
{
return false;
}
}
return true;
}
int main()
{
struct Head x = {};
Phead ph = &x;
Insert_key(ph, 12);
Insert_key(ph, 48);
Insert_key(ph, 25);
Insert_key(ph, 37);
Insert_key(ph, 15);
Insert_key(ph, 16);
Insert_key(ph, 29);
Insert_key(ph, 67);
Insert_key(ph, 56);
Insert_key(ph, 22);
Insert_key(ph, 34);
Insert_key(ph, 47);
Print(ph);
}
4、公共溢出区法
4、一致性哈希
**个人理解:**假设有三个服务器ABC,每台服务器只能存2W张照片,现在有三万张照片,理想情况下,每台服务器存一万张,假设存完之后,A坏了,那请问接下来存储是对2取余还是对3取余,那就只能将所有照片取出来,然后对2取余,然后重新存。
一致性哈希就是将添加或删除服务器时对数据存储的影响降到了最低。
一致性哈希存在问题:当一台服务器坏了,会有三分之一的数据会将压力给下一台服务器,会导致多米诺效应。因此当服务器越多时,影响越
5、虚拟节点
虚拟(节点/服务器)越多,某台服务器坏掉之后,受到影响会被分压。
一致性哈希存在问题:当一台服务器坏了,会有三分之一的数据会将压力给下一台服务器,会导致多米诺效应。因此当服务器越多时,影响越小
5、虚拟节点
虚拟(节点/服务器)越多,某台服务器坏掉之后,受到影响会被分压。
标签:Insert,hash,哈希,Phead,key,ph,NULL 来源: https://blog.csdn.net/m0_57519884/article/details/120884203