抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

哈希表

通过数组下标索引到值

任意类型映射成一个整型 (下标)

简单举例

val % size

假如 val = 16、size = 9

16 % 9 = 7 (下标)

假如 val = 7、size = 9

7 % 9 = 7 (下标) 产生冲突了 - 优秀的哈希都会冲突

下标 0 1 2 3 4 5 6 7 8
16

解决哈希冲突的 四 种 方法

  1. 开放定值法
  2. 拉链法
  3. 在哈希法 (在散列法)
  4. 建立公共溢出区

解决哈希冲突方法 - 开放定值法

可以使用开放定值法 (二次探测法) - 不好用会堆聚

下标7后面8是空着的所以7可以存放到此处

下标 0 1 2 3 4 5 6 7 8
16 7

解决哈希冲突方法 - 拉链法

顾名思义拉链法就是以下标为7的位置做成一个链表

下标 0 1 2 3 4 5 6 7 8
16
7

解决哈希冲突方法 - 在哈希法 (在散列法)

如果第一个哈希函数冲突了,那么就可以利用第二个哈希函数在去做映射,如果在冲突了那么就利用第三个哈希函数在做。。。(禁止套娃)🤐

解决哈希冲突方法 - 建立公共溢出区

将冲突的元素集中去管理

时间复杂度

平均复杂度 : $O(1)$

字符串-哈希

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*************************************************************************
> File Name: 哈希.c
> Author: 秃头王
> Mail: 1658339000@qq.com
> Created Time: 2022年01月21日 星期五 16时28分39秒
************************************************************************/

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

typedef struct Node {
char *str;
struct Node *next;
} Node;

typedef struct HashTable {
Node **data;
int size;
} HashTable;

Node *init_node(char *str, Node *head) {
Node *p =(Node *)malloc(sizeof(Node));
// 深拷贝
p->str = strdup(str);
p->next = head;
return p;
}

HashTable *init_hash(int n) {
HashTable *h = (HashTable *)malloc(sizeof(HashTable));
// 利用率
h->size = (n << 1);
h->data = (Node **)calloc(h->size, sizeof(Node *));
return h;
}

int BKDRHash(char *str) {
// seed 可以是任意一质数
int seed = 31, hash = 0;
for(int i = 0; str[i]; i++) hash = hash * seed + str[i];
// 确保 head 是一个正数
return hash & 0x7fffffff;
}

int insert(HashTable *h, char *str) {
if(h == NULL) return 0;
int hash = BKDRHash(str);
int ind = hash % h->size;
h->data[ind] = init_node(str, h->data[ind]);
return 1;
}

int search(HashTable *h, char *str) {
if(h == NULL) return 0;
int hash = BKDRHash(str);
int ind = hash % h->size;
Node *p = h->data[ind];
while(p && strcmp(p->str, str)) p = p->next;
return p != NULL;
}

void clear_node(Node *node) {
if(node == NULL) return ;
Node *p = node, *t;
while(p) {
t = p->next;
free(p->str);
free(p);
p = t;
}
return ;
}

void clear(HashTable *h) {
if(h == NULL) return ;
for(int i = 0; i < h->size; i++) {
clear_node(h->data[i]);
}
free(h);
return ;
}

int main() {
#define MAX_N 100
int op;
char str[MAX_N + 5] = {0};
HashTable *h = init_hash(MAX_N);
while(~scanf("%d%s", &op, str)) {
switch(op) {
case 0 : {
printf("insert %s to HashTable\n", str);
insert(h, str);
} break;
case 1 : {
printf("search %s from HashTable result = %d\n", str, search(h, str));
}break;
}
}
#undef MAX_N
clear(h);
return 0;
}

评论