其他分享
首页 > 其他分享> > 哈希(hash)

哈希(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