哈希表基础以及用拉链法解决冲突问题

哈希表,是根据关键字值(Key)直接进行访问的数据结构,它通过把关键字映射到表中一个位置(数组下标)来直接访问,以加快查找关键值的速度。这个映射函数叫做哈希函数,存放记录的数组叫做哈希表
给定表M,存在函数f(key),存在函数f(key),对任意的关键字值key,待入函数后若能得到包含该关键字的表中地址,称表M为哈希表,函数f(key)为哈希函数。

//哈希表用来访问
#include <stdio.h>
#include <string>
int main() {
	int char_map[128] = { 0 };
	std::string str = "abcdefgaaxxy";
	//统计字符串中,各个字符的数量
	for (int i = 0; i < str.length(); i++) {
		char_map[str[i]]++;
	}
	for (int i = 0; i < 128; i++) {
		if (char_map[i] > 0) {
			printf("[%c][%d] : %d\n", i, i, char_map[i]);
		}
	}
	return 0;
}
//哈希表用来排序
//时间复杂度O(表长+n),n为元素个数
//哈希表排序长度,需要超过最大待排序的数字
#include <stdio.h>
int main() {
	int random[10] = { 999, 1, 444, 7, 20, 9, 1, 3, 7, 7 };
	int hash_map[1000] = { 0 };
	for (int i = 0; i < 10; i++) {
		hash_map[random[i]]++;
	}
	for (int i = 0; i < 1000; i++) {
		for (int j = 0; j < hash_map[i]; j++) {
			printf("%d\n", i);
		}
	}
	return 0;
}

利用哈希函数,将关键字(key)转化为整数再对表长取余,从而关键字值转化为哈希表的表长范围内的整数
拉链法解决冲突,构造哈希表
将所有哈希函数结果相同的结点连接在同一个单链表中。
若选定的哈希表长度为m,则可将哈希表定义为一个长度为m的指针数组t[0-m-1],指针数组中的每个指针指向哈希函数结果相同的单链表
插入value:
将元素value插入哈希表,若元素value的哈希函数值为hash_key,将value对应的节点以头插法的方式插入到以t[hash_key]为头指针的单链表中。
查找value:
若元素value的哈希函数值为hash_key,遍历以t[hash_key]为头指针的单链表,查找链表各个节点的值域是否为value.

#include <stdio.h>
#include <vector>
//哈希表即为普通的单链表构成
struct ListNode {
	int val;
	ListNode* next;
	ListNode(int x) : val(x), next(NULL){}
};
//整数哈希函数,直接取余
int hash_func(int key, int table_len) {
	return key % table_len;
}
//将元素插入哈希表
void insert(ListNode* hash_table[], ListNode* node, int table_len) {
	int hash_key = hash_func(node->val, table_len);
	node->next = hash_table[hash_key];    //使用头插法插入节点
	hash_table[hash_key] = node;
}

bool search(ListNode* hash_table[], int value, int table_len) {
	int hash_key = hash_func(value, table_len);
	ListNode* head = hash_table[hash_key];
	while (head)
	{
		if (head->val == value) {
			return true;
		}
		head = head->next;
	}
	return false;
}
//TABLE_LEN取为质数,冲突会比其他数字少
int main() {
	const int TABLE_LEN = 11;
	ListNode* hash_table[TABLE_LEN] = { 0 };
	std::vector<ListNode*> hash_node_vec;
	int test[8] = { 1,1,4,9,20,30,150,500 };
	for (int i = 0; i < 8; i++) {
		hash_node_vec.push_back(new ListNode(test[i]));
	}
	for (int i = 0; i < hash_node_vec.size(); i++) {
		insert(hash_table, hash_node_vec[i], TABLE_LEN);
	}
	printf_s("Hash table:\n");
	for (int i = 0; i < TABLE_LEN; i++) {
		printf_s("[%d]:", i);
		ListNode* head = hash_table[i];
		while (head) {
			printf_s("->%d", head->val);
			head = head->next;
		}
		printf_s("\n");
	}
	printf_s("\n");
	printf_s("Test search:\n");
	for (int i = 0; i < 10; i++) {
		if (search(hash_table, i, TABLE_LEN) ){
			printf_s("%d is in the hash table.\n", i);
		}
		else {
			printf_s("%d is not in the hash table.\n", i);
		}
	}
	return 0;
}

结果如下:
在这里插入图片描述
哈希map与STLmap

#include <stdio.h>
#include <map>
#include <string>

struct ListNode {
	std::string key;
	int val;
	ListNode* next;
	ListNode(int x):val(x),next(NULL){}
};

int main() {
	std::map<std::string, int> hash_map;
	std::string str1 = "abc";
	std::string str2 = "aaa";
	std::string str3 = "xxxxxx";
	hash_map[str1] = 1;
	hash_map[str2] = 2;
	hash_map[str3] = 100;
	if (hash_map.find(str1) != hash_map.end()) {
		printf_s("%s is in hash_map, value is %d\n", str1.c_str(), hash_map[str1]);
	}
	std::map<std::string, int>::iterator it;
	for (it = hash_map.begin(); it != hash_map.end(); it++) {
		printf{ "hash_map[%s] = %d\n", it->first.c_str(), it->second };
	}
	return 0;
}
  • 0
    点赞
  • 5
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页
评论

打赏作者

不会code的菜鸟

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值