文章目录
- 前言
- 一、哈希
- 二、哈希的具体实现
- 2.1 准备工作
- 2.2 插入数据
- 2.3 输出哈希表
- 2.4 在哈希表中寻找数据
- 2.5 销毁哈希表
- 三、 哈希表的调用
- 总结
前言
本期主要和大家介绍一下哈希算法,这里主要给出哈希算法的实现方法;
一、哈希
hash是一种算法:
哈希冲突(哈希碰撞):不同的数据通过哈希算法映射出来的键值相同
解决办法:通过在键值相同的位置加入链表存储数据
二、哈希的具体实现
2.1 准备工作
(1)宏定义10个(表示指针数组的容量为10)-------指针数组(一个数组中的元素都是指针);
(2)定义链表节点的结构体;
(3)定义一个容量为MAXLEN的指针数组;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 10
typedef struct node
{
int Data;
struct node *pNext;
}LinkNode;
LinkNode *HashTable[MAXLEN];
2.2 插入数据
由于指针数组中最终存放的10个键值链表的首地址,所以应该定义二级指针,以此修改指针数组中指针所指向的地址,其实修改的是地址的地址;销毁板门认真看注释哦!
int InsertHashTable(int TmpData)
{
int index = 0;
LinkNode **ppTmp = NULL; //指向链表中第一个元素
LinkNode *pNode = NULL;
index = TmpData % MAXLEN; //以每个数据的个位数来作为键值
for (ppTmp = &HashTable[index]; *ppTmp != NULL && TmpData > (*ppTmp)->Data; ppTmp = &(*ppTmp)->pNext)
{
} //找到合适的位置(按照元素大小排列,判断条件中如果是空跳出循环,如果要插入的数据大于当前数据,那么也跳出循环,接下来只需要在当前数据的后面插入数据即可),准备插入数据
pNode = malloc(sizeof(LinkNode)); //为即将插入的数据创建链表节点
if (NULL == pNode)
{
perror("fail to malloc");
return -1;
}
pNode->Data = TmpData; //将数据存入链表节点
pNode->pNext = *ppTmp; //将插入的数据节点指向原来前一个节点的下一个
*ppTmp = pNode; //将原来前一个节点指向目前插入的节点
return 0;
}
2.3 输出哈希表
这里重点解释一下这句代码: ppTmp = &(*ppTmp)->pNext
(1)ppTmp是一个二级指针。*ppTmp 表示LinkNode *类型,也就是节点指针类型
(2)(*ppTmp)->pNext表示指向下一个节点;
(3)&(ppTmp)->pNext,这里的&是因为ppTmp是二级指针类型,为了使得类型匹配;这里也可以换成ppTmp = (*ppTmp)->pNext;但是为了代码整齐,前面是从ppTmp开始的,所以后面也使用ppTmp;
int ShowHashTable(void)
{
int i = 0;
LinkNode **ppTmp = NULL;
for (i = 0; i < MAXLEN; ++i)
{
printf("%2d:", i);
for (ppTmp = &HashTable[i]; *ppTmp != NULL; ppTmp = &(*ppTmp)->pNext)
{
printf("%d ", (*ppTmp)->Data);
}
printf("\n");
}
}
2.4 在哈希表中寻找数据
int FindHashTable(int TmpData)
{
int index = 0;
LinkNode **ppTmp = NULL;
index = TmpData % MAXLEN; //先拿到键值,再去相应链表寻找
for (ppTmp = &HashTable[index]; *ppTmp != NULL && TmpData >= (*ppTmp)->Data; ppTmp = &(*ppTmp)->pNext) //在键值对应的链表遍历一遍寻找
{
if (TmpData == (*ppTmp)->Data)
{
return 1;
}
}
return 0;
}
2.5 销毁哈希表
思想是销毁链表即可,因为哈希表就是多个链表组合起来的;
int DestroyHashTable(void)
{
LinkNode *pTmpNode = NULL;
LinkNode *pFreeNode = NULL;
int i = 0;
for (i = 0; i < MAXLEN; ++i)
{
pTmpNode = HashTable[i];
pFreeNode = pTmpNode;
while (pTmpNode != NULL)
{
pTmpNode = pTmpNode->pNext;
free(pFreeNode);
pFreeNode = pTmpNode;
}
}
return 0;
}
三、 哈希表的调用
主函数中的内容是对上述几个函数的应用:
int main(int argc, const char *argv[])
{
InsertHashTable(12);
InsertHashTable(12);
InsertHashTable(13);
InsertHashTable(15);
InsertHashTable(22);
InsertHashTable(23);
InsertHashTable(35);
InsertHashTable(89);
InsertHashTable(80);
InsertHashTable(90);
InsertHashTable(90);
InsertHashTable(99);
InsertHashTable(9);
InsertHashTable(10);
InsertHashTable(1);
ShowHashTable();
if (FindHashTable(80))
{
printf("Found!\n");
}
DestroyHashTable();
return 0;
}
测试的结果如下:
总结
本期主要分享的是数据插入哈希表,在哈希表中查找数据,并且遍历哈希表的操作,哈希表是一种散列存储结构,在嵌入式应用中比较广泛,希望各位小伙伴们学起来,练起来,一起加油!最后,各位小伙伴们如果喜欢我的分享可以点赞收藏哦,你们的认可是我创作的动力,一起加油!