哈希表(hashtable)的数据插入、查找和遍历

文章目录

  • 前言
  • 一、哈希
  • 二、哈希的具体实现
    • 2.1 准备工作
    • 2.2 插入数据
    • 2.3 输出哈希表
    • 2.4 在哈希表中寻找数据
    • 2.5 销毁哈希表
  • 三、 哈希表的调用
  • 总结


前言

本期主要和大家介绍一下哈希算法,这里主要给出哈希算法的实现方法;


一、哈希

hash是一种算法:
哈希冲突(哈希碰撞):不同的数据通过哈希算法映射出来的键值相同
解决办法:通过在键值相同的位置加入链表存储数据

二、哈希的具体实现

2.1 准备工作

(1)宏定义10个(表示指针数组的容量为10)-------指针数组(一个数组中的元素都是指针);
(2)定义链表节点的结构体;
(3)定义一个容量为MAXLEN的指针数组;

#include 
#include 
#include 

#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;
}

测试的结果如下:
哈希表(hashtable)的数据插入、查找和遍历_第1张图片


总结

本期主要分享的是数据插入哈希表,在哈希表中查找数据,并且遍历哈希表的操作,哈希表是一种散列存储结构,在嵌入式应用中比较广泛,希望各位小伙伴们学起来,练起来,一起加油!最后,各位小伙伴们如果喜欢我的分享可以点赞收藏哦,你们的认可是我创作的动力,一起加油!

你可能感兴趣的:(数据结构,散列表,链表,数据结构,linux,嵌入式硬件,arm开发)