Skip to content

Commit 62b6751

Browse files
committed
add files
1 parent fb595af commit 62b6751

File tree

24 files changed

+2748
-37
lines changed

24 files changed

+2748
-37
lines changed

data-structure/hash/HashMap.java

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
// import java.util.LinkedList;
2+
3+
public class HashMap {
4+
private static final int INITIAL_CAPACITY = 10;
5+
private static final double LOAD_FACTOR = 0.75;
6+
7+
private Entry[] table;
8+
private int size;
9+
private int capacity;
10+
11+
// 哈希表的元素结构体
12+
public class Entry {
13+
String key;
14+
int value;
15+
Entry next; // 用于链表解决冲突
16+
17+
public Entry(String key, int value) {
18+
this.key = key;
19+
this.value = value;
20+
this.next = null;
21+
}
22+
}
23+
24+
// 初始化 HashMap
25+
public HashMap() {
26+
this.size = 0;
27+
this.capacity = INITIAL_CAPACITY;
28+
this.table = new Entry[this.capacity];
29+
}
30+
31+
// 哈希函数
32+
private int hash(String key) {
33+
int hashValue = 0;
34+
for (int i = 0; i < key.length(); i++) {
35+
hashValue = (hashValue * 31) + key.charAt(i);
36+
}
37+
return Math.abs(hashValue) % this.capacity;
38+
}
39+
40+
// 扩容
41+
private void resize() {
42+
int newCapacity = this.capacity * 2;
43+
Entry[] newTable = new Entry[newCapacity];
44+
45+
// 迁移原表的数据到新表
46+
for (int i = 0; i < this.capacity; i++) {
47+
Entry entry = this.table[i];
48+
while (entry != null) {
49+
int newIndex = hash(entry.key) % newCapacity;
50+
Entry newEntry = new Entry(entry.key, entry.value);
51+
newEntry.next = newTable[newIndex];
52+
newTable[newIndex] = newEntry;
53+
54+
entry = entry.next;
55+
}
56+
}
57+
58+
this.capacity = newCapacity;
59+
this.table = newTable;
60+
}
61+
62+
// 插入键值对(如果存在则更新)
63+
public void put(String key, int value) {
64+
// 判断是否需要扩容
65+
if ((double) this.size / this.capacity > LOAD_FACTOR) {
66+
resize();
67+
}
68+
69+
int index = hash(key);
70+
Entry entry = this.table[index];
71+
72+
// 遍历链表,检查是否已经存在相同的键
73+
while (entry != null) {
74+
if (entry.key.equals(key)) {
75+
entry.value = value; // 更新值
76+
return;
77+
}
78+
entry = entry.next;
79+
}
80+
81+
// 如果没有找到相同的键,插入新键值对
82+
Entry newEntry = new Entry(key, value);
83+
newEntry.next = this.table[index];
84+
this.table[index] = newEntry;
85+
this.size++;
86+
}
87+
88+
// 查找键
89+
public int get(String key) {
90+
int index = hash(key);
91+
Entry entry = this.table[index];
92+
93+
while (entry != null) {
94+
if (entry.key.equals(key)) {
95+
return entry.value;
96+
}
97+
entry = entry.next;
98+
}
99+
return -1; // 返回 -1 表示未找到
100+
}
101+
102+
// 删除键
103+
public void delete(String key) {
104+
int index = hash(key);
105+
Entry entry = this.table[index];
106+
Entry prev = null;
107+
108+
while (entry != null) {
109+
if (entry.key.equals(key)) {
110+
if (prev == null) {
111+
this.table[index] = entry.next;
112+
} else {
113+
prev.next = entry.next;
114+
}
115+
this.size--;
116+
return;
117+
}
118+
prev = entry;
119+
entry = entry.next;
120+
}
121+
}
122+
123+
// 测试
124+
public static void main(String[] args) {
125+
HashMap map = new HashMap();
126+
map.put("apple", 10);
127+
map.put("banana", 20);
128+
map.put("orange", 30);
129+
130+
System.out.println("apple: " + map.get("apple"));
131+
System.out.println("banana: " + map.get("banana"));
132+
System.out.println("grape: " + map.get("grape"));
133+
134+
map.delete("banana");
135+
System.out.println("banana after delete: " + map.get("banana"));
136+
}
137+
}
138+
139+
/*
140+
* jarry@MacBook-Pro hash % javac HashMap.java
141+
* jarry@MacBook-Pro hash % java HashMap
142+
* apple: 10
143+
* banana: 20
144+
* grape: -1
145+
* banana after delete: -1
146+
*/

data-structure/hash/hash_map.c

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
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

Comments
 (0)