Bootstrap

哈希表——C语言

哈希表(Hash Table)是一种高效的数据结构,能够在平均情况下实现常数时间的查找、插入和删除操作。

        哈希表的核心是哈希函数,哈希函数是一个将输入数据(通常称为“键”或“key”)转换为固定长度的整数的函数。这个整数通常用作哈希表(Hash Table)中的索引,用于快速查找数据。本质上就是根据输入的值确定值的位置。

例如,输入除以10取余是位置编号:

int HashPosFind(int num) {
	return num % 10;
}

如果有重复的情况呢,那么要在其他位置存储,有不同的方法,这里采取的是链表法。

如图所示,如果序号为1的地址处已经有值存在,那么我们就把新的数连接到链表上。

首先我们可以写出类似于这样的函数:

#define NUM 10
#define Nan -32767
typedef struct Seqlist {
	struct Seqlist* next;
	int val;
}Seqlist;

typedef struct HashList {
	int num;
	Seqlist** list;
}HashList;
HashList* HashInit() {
	HashList* H = (HashList*)malloc(sizeof(HashList));
	H->num = 0;
	H->list = (Seqlist**)malloc(sizeof(Seqlist*) *NUM);
	for (int i = 0; i < NUM; i++) {
		H->list[i] = (Seqlist*)malloc(sizeof(Seqlist));
		H->list[i]->next = NULL;
	}

	for (int i = 0; i < NUM; i++) {
		H->list[i]->val = Nan;
	}
	return H;
}

1.首先定义NUM表示一共有十个位置定义链表,定义Nan表示没有数的时候的数值。
2.然后定义哈希表的结构,用二级指针的方法模拟二维数组,准确的说是二维链表。
3.接着为哈希表开辟空间,先为10个链表指针开辟二级指针(指针数组),接着在为每个序列号指针开辟空间并且初始化为Nan表示此时哈希表为空。

        接着就是哈希表插入操作,这里要考虑两种情况,第一是当取得地址序列号之后,此时的链表存储的是Nan,那我们要先把链表的Nan赋值为插入的数据,然后新创建一个节点存储Nan表示链表的结尾。
        第二种情况的是第一个数值不是Nan,这时要一直找到链表的尾,然后同样执行上一步的操作:先赋值为插入的数值,然后更新链表的尾。

代码如下:

void HashPush(int val,HashList* H) {
	int pos = HashPosFind(val);
	if (H->list[pos]->val == Nan) {
		H->list[pos]->val = val;
		Seqlist* new_node = (Seqlist*)malloc(sizeof(Seqlist));
		new_node->val = Nan;
		new_node->next = NULL;
		H->list[pos]->next = new_node;
	}
	else {
		printf("重新插入中\n");
		int num = 1;
		Seqlist* cur = H->list[pos];
		while (cur->val != Nan) {
			cur = cur->next;
		}
		Seqlist* new_node = (Seqlist*)malloc(sizeof(Seqlist));
		new_node->val = Nan;
		new_node->next = NULL;
		cur->next = new_node;
		cur->val = val;
	}
}

        首先是第一种情况,因为是Nan所以说明此时的链表为空,所以直接存储,然后开辟一个新的节点存储Nan表示链表的结尾。

        第二种情况说明已经有值存在,这时先找到链表的尾(找到节点值为Nan的节点),然后执行和第一步一样的操作:先存储值,然后新开辟一个节点存储Nan。

        最后是打印函数:思路比较简单,一直打印到Nan为止。

void HashPrint(HashList* H) {

	for (int i = 0; i < NUM; i++) {
		printf("%d: ",i);
		Seqlist* cur = H->list[i];
		while (cur->val != Nan) {
			printf("%d ", cur->val);
			cur = cur->next;
		}
		printf("\n");
	}
}

这就是文章的全部的内容了,希望对你有所帮助,如有错误欢迎指出。

;