1+ #include <stdio.h>
2+ #include <stdlib.h>
3+ #include <string.h>
4+
5+ #define INITIAL_CAPACITY 10
6+ #define LOAD_FACTOR 0.75
7+
8+ // 哈希表的元素结构体
9+ typedef struct Entry {
10+ char * key ;
11+ int value ;
12+ struct Entry * next ; // 用于链表解决冲突
13+ } Entry ;
14+
15+ // 哈希表结构体
16+ typedef struct {
17+ Entry * * table ; // 哈希表数组
18+ int size ; // 哈希表中存储的元素数量
19+ int capacity ; // 哈希表的容量
20+ } HashMap ;
21+
22+ // 哈希函数(使用简单的字符串哈希函数)
23+ unsigned int hash (const char * key , int capacity ) {
24+ unsigned int hashValue = 0 ;
25+ while (* key ) {
26+ hashValue = (hashValue * 31 ) + * key ;
27+ key ++ ;
28+ }
29+ return hashValue % capacity ;
30+ }
31+
32+ // 初始化 HashMap
33+ void initHashMap (HashMap * map ) {
34+ map -> size = 0 ;
35+ map -> capacity = INITIAL_CAPACITY ;
36+ map -> table = (Entry * * )malloc (sizeof (Entry * ) * map -> capacity );
37+ for (int i = 0 ; i < map -> capacity ; i ++ ) {
38+ map -> table [i ] = NULL ;
39+ }
40+ }
41+
42+ // 重新分配容量,扩容 HashMap
43+ void resizeMap (HashMap * map ) {
44+ int newCapacity = map -> capacity * 2 ;
45+ Entry * * newTable = (Entry * * )malloc (sizeof (Entry * ) * newCapacity );
46+
47+ // 初始化新表
48+ for (int i = 0 ; i < newCapacity ; i ++ ) {
49+ newTable [i ] = NULL ;
50+ }
51+
52+ // 迁移原表数据到新表
53+ for (int i = 0 ; i < map -> capacity ; i ++ ) {
54+ Entry * entry = map -> table [i ];
55+ while (entry ) {
56+ int newIndex = hash (entry -> key , newCapacity );
57+ Entry * newEntry = (Entry * )malloc (sizeof (Entry ));
58+ newEntry -> key = strdup (entry -> key );
59+ newEntry -> value = entry -> value ;
60+ newEntry -> next = newTable [newIndex ];
61+ newTable [newIndex ] = newEntry ;
62+
63+ entry = entry -> next ;
64+ }
65+ }
66+
67+ // 释放原表并更新哈希表
68+ for (int i = 0 ; i < map -> capacity ; i ++ ) {
69+ Entry * entry = map -> table [i ];
70+ while (entry ) {
71+ Entry * next = entry -> next ;
72+ free (entry -> key );
73+ free (entry );
74+ entry = next ;
75+ }
76+ }
77+ free (map -> table );
78+ map -> table = newTable ;
79+ map -> capacity = newCapacity ;
80+ }
81+
82+ // 插入键值对(如果存在则更新)
83+ void put (HashMap * map , const char * key , int value ) {
84+ // 判断是否需要扩容
85+ if ((float )map -> size / map -> capacity > LOAD_FACTOR ) {
86+ resizeMap (map );
87+ }
88+
89+ int index = hash (key , map -> capacity );
90+ Entry * entry = map -> table [index ];
91+
92+ // 遍历链表,检查是否已经存在相同的键
93+ while (entry ) {
94+ if (strcmp (entry -> key , key ) == 0 ) {
95+ entry -> value = value ; // 更新值
96+ return ;
97+ }
98+ entry = entry -> next ;
99+ }
100+
101+ // 如果没有找到相同的键,插入新键值对
102+ Entry * newEntry = (Entry * )malloc (sizeof (Entry ));
103+ newEntry -> key = strdup (key );
104+ newEntry -> value = value ;
105+ newEntry -> next = map -> table [index ];
106+ map -> table [index ] = newEntry ;
107+ map -> size ++ ;
108+ }
109+
110+ // 查找键
111+ int get (HashMap * map , const char * key ) {
112+ int index = hash (key , map -> capacity );
113+ Entry * entry = map -> table [index ];
114+
115+ while (entry ) {
116+ if (strcmp (entry -> key , key ) == 0 ) {
117+ return entry -> value ;
118+ }
119+ entry = entry -> next ;
120+ }
121+ return -1 ; // 返回 -1 表示未找到
122+ }
123+
124+ // 删除键
125+ void delete (HashMap * map , const char * key ) {
126+ int index = hash (key , map -> capacity );
127+ Entry * entry = map -> table [index ];
128+ Entry * prev = NULL ;
129+
130+ while (entry ) {
131+ if (strcmp (entry -> key , key ) == 0 ) {
132+ if (prev ) {
133+ prev -> next = entry -> next ;
134+ } else {
135+ map -> table [index ] = entry -> next ;
136+ }
137+ free (entry -> key );
138+ free (entry );
139+ map -> size -- ;
140+ return ;
141+ }
142+ prev = entry ;
143+ entry = entry -> next ;
144+ }
145+ }
146+
147+ // 释放哈希表
148+ void freeHashMap (HashMap * map ) {
149+ for (int i = 0 ; i < map -> capacity ; i ++ ) {
150+ Entry * entry = map -> table [i ];
151+ while (entry ) {
152+ Entry * next = entry -> next ;
153+ free (entry -> key );
154+ free (entry );
155+ entry = next ;
156+ }
157+ }
158+ free (map -> table );
159+ }
160+
161+ // 测试
162+ int main () {
163+ HashMap map ;
164+ initHashMap (& map );
165+
166+ put (& map , "apple" , 10 );
167+ put (& map , "banana" , 20 );
168+ put (& map , "orange" , 30 );
169+
170+ printf ("apple: %d\n" , get (& map , "apple" ));
171+ printf ("banana: %d\n" , get (& map , "banana" ));
172+ printf ("grape: %d (not found)\n" , get (& map , "grape" ));
173+
174+ delete (& map , "banana" );
175+ printf ("banana after delete: %d\n" , get (& map , "banana" ));
176+
177+ freeHashMap (& map );
178+ return 0 ;
179+ }
180+
181+ /*
182+ jarry@MacBook-Pro hash % gcc hash_map.c
183+ jarry@MacBook-Pro hash % ./a.out
184+ apple: 10
185+ banana: 20
186+ grape: -1 (not found)
187+ banana after delete: -1
188+ */
0 commit comments