Skip to content

Commit 15bbfee

Browse files
author
huoda
committed
feat(散列表):增加散列表java实现,使用链表法解决散列冲突
1 parent 31b0908 commit 15bbfee

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed

java/18_hashtable/MyHashTable.java

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/**
2+
* @Description:散列表实现
3+
* @Author: Hoda
4+
* @Date: Create in 2019-08-07
5+
* @Modified By:
6+
* @Modified Date:
7+
*/
8+
public class MyHashTable<K, V> {
9+
10+
/**
11+
* 散列表默认长度
12+
*/
13+
private static final int DEFAULT_INITAL_CAPACITY = 8;
14+
15+
/**
16+
* 装载因子
17+
*/
18+
private static final float LOAD_FACTOR = 0.75f;
19+
20+
/**
21+
* 初始化散列表数组
22+
*/
23+
private Entry<K, V>[] table;
24+
25+
/**
26+
* 实际元素数量
27+
*/
28+
private int size = 0;
29+
30+
/**
31+
* 散列表索引数量
32+
*/
33+
private int use = 0;
34+
35+
public MyHashTable() {
36+
table = (Entry<K, V>[]) new Entry[DEFAULT_INITAL_CAPACITY];
37+
}
38+
39+
static class Entry<K, V> {
40+
K key;
41+
42+
V value;
43+
44+
Entry<K, V> next;
45+
46+
Entry(K key, V value, Entry<K, V> next) {
47+
this.key = key;
48+
this.value = value;
49+
this.next = next;
50+
}
51+
}
52+
53+
/**
54+
* 新增
55+
*
56+
* @param key
57+
* @param value
58+
*/
59+
public void put(K key, V value) {
60+
int index = hash(key);
61+
// 位置未被引用,创建哨兵节点
62+
if (table[index] == null) {
63+
table[index] = new Entry<>(null, null, null);
64+
}
65+
66+
Entry<K, V> tmp = table[index];
67+
// 新增节点
68+
if (tmp.next == null) {
69+
tmp.next = new Entry<>(key, value, null);
70+
size++;
71+
use++;
72+
// 动态扩容
73+
if (use >= table.length * LOAD_FACTOR) {
74+
resize();
75+
}
76+
}
77+
// 解决散列冲突,使用链表法
78+
else {
79+
do {
80+
tmp = tmp.next;
81+
// key相同,覆盖旧的数据
82+
if (tmp.key == key) {
83+
tmp.value = value;
84+
return;
85+
}
86+
} while (tmp.next != null);
87+
88+
Entry<K, V> temp = table[index].next;
89+
table[index].next = new Entry<>(key, value, temp);
90+
size++;
91+
}
92+
}
93+
94+
/**
95+
* 散列函数
96+
* <p>
97+
* 参考hashmap散列函数
98+
*
99+
* @param key
100+
* @return
101+
*/
102+
private int hash(Object key) {
103+
int h;
104+
return (key == null) ? 0 : ((h = key.hashCode()) ^ (h >>> 16)) % table.length;
105+
}
106+
107+
/**
108+
* 扩容
109+
*/
110+
private void resize() {
111+
Entry<K, V>[] oldTable = table;
112+
table = (Entry<K, V>[]) new Entry[table.length * 2];
113+
use = 0;
114+
for (int i = 0; i < oldTable.length; i++) {
115+
if (oldTable[i] == null || oldTable[i].next == null) {
116+
continue;
117+
}
118+
Entry<K, V> e = oldTable[i];
119+
while (e.next != null) {
120+
e = e.next;
121+
int index = hash(e.key);
122+
if (table[index] == null) {
123+
use++;
124+
// 创建哨兵节点
125+
table[index] = new Entry<>(null, null, null);
126+
}
127+
table[index].next = new Entry<>(e.key, e.value, table[index].next);
128+
}
129+
}
130+
}
131+
132+
/**
133+
* 删除
134+
*
135+
* @param key
136+
*/
137+
public void remove(K key) {
138+
int index = hash(key);
139+
Entry e = table[index];
140+
if (e == null || e.next == null) {
141+
return;
142+
}
143+
144+
Entry pre;
145+
do {
146+
pre = e;
147+
e = e.next;
148+
if (key == e.key) {
149+
pre.next = e.next;
150+
size--;
151+
return;
152+
}
153+
} while (e.next != null);
154+
}
155+
156+
/**
157+
* 获取
158+
*
159+
* @param key
160+
* @return
161+
*/
162+
public V get(K key) {
163+
int index = hash(key);
164+
Entry<K, V> e = table[index];
165+
if (e == null || e.next == null) {
166+
return null;
167+
}
168+
while (e.next != null) {
169+
e = e.next;
170+
if (key == e.key) {
171+
return e.value;
172+
}
173+
}
174+
return null;
175+
}
176+
}

0 commit comments

Comments
 (0)