Skip to content

Commit d0dad53

Browse files
committed
2017.4.15
Add HashTable
1 parent afd72e0 commit d0dad53

File tree

6 files changed

+283
-22
lines changed

6 files changed

+283
-22
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/**
2+
* Author: Juntaran
3+
* Email: Jacinthmail@gmail.com
4+
* Date: 2017/4/15 09:06
5+
*/
6+
7+
package Hash_Table
8+
9+
import (
10+
"Golang_Algorithm/Data_Structure/Link_List"
11+
"fmt"
12+
"math"
13+
"errors"
14+
)
15+
16+
// 设置哈希表桶个数,如果达到最大会resize,翻倍桶数量
17+
const fillRate int = 10
18+
19+
// 哈希表结构
20+
type HashTable struct {
21+
table []*Link_List.List // 底层结构
22+
size int // 当前哈希表中元素数
23+
capacity int // 最大容量,超过会resize
24+
}
25+
26+
// 子结构把kv加入哈希表,这是存储在每个bucket的链表的值
27+
type item struct {
28+
key string
29+
value interface{}
30+
}
31+
32+
// 使用的哈希算法
33+
func hashCode(s string) int {
34+
hash := int32(0)
35+
for i := 0; i < len(s); i++ {
36+
hash = int32(hash << 5-hash) + int32(s[i])
37+
hash &= hash
38+
}
39+
return int(math.Abs(float64(hash)))
40+
}
41+
42+
// 利用string类型的key来寻找bucket,也就是第几个链表
43+
func (hashTable *HashTable)getIndex(key string, length int) int {
44+
return hashCode(key) % length
45+
}
46+
47+
// 在指定的bucket内寻找指定的key,返回*tableNode
48+
func (hashTable *HashTable) find(index int, key string) (*item, error) {
49+
list := hashTable.table[index]
50+
if list == nil {
51+
return nil, errors.New("Error: Not Found")
52+
}
53+
var val *item
54+
list.DoEach(func(node Link_List.ListNode) {
55+
// 类型断言 如果传入的值为*hashNode类型,则获取其值,否则panic
56+
if node.Value.(*item).key == key {
57+
val = node.Value.(*item)
58+
}
59+
})
60+
if val == nil {
61+
return nil, errors.New("Error: Not Found")
62+
}
63+
return val, nil
64+
}
65+
66+
// 创建一个哈希表
67+
func New(size int) *HashTable {
68+
newHashTable := &HashTable {
69+
table: make([]*Link_List.List, size),
70+
size: 0,
71+
capacity: fillRate * size,
72+
}
73+
return newHashTable
74+
}
75+
76+
// 返回一个默认哈希表,默认大小为128
77+
func NewDefault() *HashTable {
78+
return New(128)
79+
}
80+
81+
// 让哈希表变大,每个桶里的元素就变少了,用更多内存降低碰撞
82+
func (hashTable *HashTable) resizeTable() {
83+
newHashTable := New(2 * len(hashTable.table))
84+
for _, list := range hashTable.table {
85+
if list != nil {
86+
for _, itemi := range list.Items() {
87+
// ok的作用是如果类型断言失败,那么parsed仍然存在,不过为零值
88+
if parsed, ok := (*itemi).(item); ok {
89+
newHashTable.Insert(parsed.key, parsed.value)
90+
} else {
91+
fmt.Println("Failed to Parse item in resize")
92+
}
93+
}
94+
}
95+
}
96+
hashTable = newHashTable
97+
}
98+
99+
// 插入一个键值对
100+
func (hashTable *HashTable) Insert(key string, value interface{}) {
101+
index := hashTable.getIndex(key, len(hashTable.table))
102+
// 如果当前桶为空
103+
if hashTable.table[index] == nil {
104+
hashTable.table[index] = Link_List.New()
105+
}
106+
item := &item{
107+
key: key,
108+
value: value,
109+
}
110+
ret, err := hashTable.find(index, key)
111+
if err != nil {
112+
// 这个bucket内不存在这个key
113+
hashTable.table[index].Append(item)
114+
hashTable.size ++
115+
} else {
116+
// key存在,覆盖
117+
ret.value = value
118+
}
119+
}
120+
121+
// 删除一个键值对
122+
func (hashTable *HashTable) Delete(key string) error {
123+
index := hashTable.getIndex(key, len(hashTable.table))
124+
list := hashTable.table[index]
125+
var val *item
126+
127+
list.DoEach(func(node Link_List.ListNode) {
128+
if node.Value.(*item).key == key {
129+
val = node.Value.(*item)
130+
}
131+
})
132+
133+
if val == nil {
134+
return errors.New("Error: Delete Not Found")
135+
}
136+
hashTable.size --
137+
return list.Remove(val)
138+
}
139+
140+
// 判断一个key是否存在
141+
func (hashTable *HashTable) ContainsKey(key string) bool {
142+
index := hashTable.getIndex(key, len(hashTable.table))
143+
item, _ := hashTable.find(index, key)
144+
if item == nil {
145+
return false
146+
}
147+
return true
148+
}
149+
150+
151+
// 根据key取value
152+
func (hashTable *HashTable) GetValue(key string) (interface{}, error) {
153+
index := hashTable.getIndex(key, len(hashTable.table))
154+
item, err := hashTable.find(index, key)
155+
if item == nil {
156+
return "", errors.New("Error: GetValue Not Found")
157+
}
158+
return item.value, err
159+
}
160+
161+
// 返回哈希表大小
162+
func (hashTable *HashTable) ReturnSize() int {
163+
return hashTable.size
164+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Author: Juntaran
3+
* Email: Jacinthmail@gmail.com
4+
* Date: 2017/4/14 06:47
5+
*/
6+
7+
package main
8+
9+
import (
10+
"Golang_Algorithm/Data_Structure/Hash_Table"
11+
"fmt"
12+
"log"
13+
)
14+
15+
func main() {
16+
hashTable := Hash_Table.New(5)
17+
hashTable.Insert("foo", "bar")
18+
hashTable.Insert("fiz", "buzz")
19+
20+
fmt.Println("Size:", hashTable.ReturnSize())
21+
ret := hashTable.ContainsKey("foo1")
22+
fmt.Println(ret)
23+
24+
val, err := hashTable.GetValue("foo6")
25+
if err == nil {
26+
fmt.Println(val)
27+
} else {
28+
log.Println(err)
29+
}
30+
31+
hashTable.Insert("foo", "bomb")
32+
fmt.Println("Size:", hashTable.ReturnSize())
33+
val, err = hashTable.GetValue("foo")
34+
if err == nil {
35+
fmt.Println(val)
36+
} else {
37+
log.Println(err)
38+
}
39+
40+
err = hashTable.Delete("foo")
41+
if err != nil {
42+
log.Println(err)
43+
}
44+
fmt.Println("Delete Size:", hashTable.ReturnSize())
45+
val, err = hashTable.GetValue("foo")
46+
if err == nil {
47+
fmt.Println(val)
48+
} else {
49+
log.Println(err)
50+
}
51+
}

Data_Structure/Link_List/link_list.go

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
)
1414

1515
type ListNode struct { // 链表元素结构
16-
value interface{}
16+
Value interface{}
1717
next *ListNode
1818
prev *ListNode
1919
}
@@ -39,7 +39,7 @@ func (list *List) Prepend(value interface{}) {
3939
defer list.lock.Unlock()
4040
{
4141
node := new(ListNode)
42-
node.value = value
42+
node.Value = value
4343
if list.length == 0 {
4444
list.head = node
4545
list.tail = node
@@ -58,7 +58,7 @@ func (list *List) Append(value interface{}) {
5858
defer list.lock.Unlock()
5959
{
6060
node := new(ListNode)
61-
node.value = value
61+
node.Value = value
6262

6363
if list.length == 0 {
6464
list.head = node
@@ -82,7 +82,7 @@ func (list *List) Insert(value interface{}, index int) error {
8282
defer list.lock.Unlock()
8383
{
8484
node := new(ListNode)
85-
node.value = value
85+
node.Value = value
8686
if list.length == 0 {
8787
list.head = node
8888
list.tail = node
@@ -129,6 +129,32 @@ func (list *List) DeleteIndex(index int) error {
129129
}
130130
}
131131

132+
// 删除元素
133+
func (list *List) Remove(value interface{}) error {
134+
if list.length == 0 {
135+
return errors.New("Error: List Empty")
136+
}
137+
if list.head.Value == value {
138+
list.head = list.head.next
139+
list.length --
140+
return nil
141+
}
142+
found := 0
143+
for node := list.head; node != nil; node = node.next {
144+
if *node.Value.(*ListNode) == value && found == 0 {
145+
node.next.prev = node.prev
146+
node.prev.next = node.next
147+
list.length --
148+
found ++
149+
}
150+
}
151+
if found == 0 {
152+
return errors.New("Error: Node not found")
153+
}
154+
return nil
155+
}
156+
157+
132158
// 删除所有值为value的元素
133159
func (list *List) DeleteValue(value interface{}) (int, error) {
134160
list.lock.Lock()
@@ -143,21 +169,21 @@ Here:
143169
return count, nil
144170
}
145171
// 链表头的值恰好为value
146-
if list.head.value == value {
172+
if list.head.Value == value {
147173
list.head = list.head.next
148174
list.length --
149175
count ++
150176
goto Here
151177
}
152178
for node := list.head; node.next != nil; node = node.next {
153-
if node.value == value {
179+
if node.Value == value {
154180
node.prev.next = node.next
155181
node.next.prev = node.prev
156182
list.length --
157183
count ++
158184
}
159185
}
160-
if list.tail.value == value {
186+
if list.tail.Value == value {
161187
count ++
162188
list.tail.prev.next = nil
163189
list.length --
@@ -223,7 +249,7 @@ func (list *List) GetIndex(index int) (interface{}, error) {
223249
for i := 1; i < index; i++ {
224250
node = node.next
225251
}
226-
return node.value, nil
252+
return node.Value, nil
227253
}
228254
}
229255

@@ -239,7 +265,7 @@ func (list *List) FindIndex(value interface{}) ([]int, int) {
239265
count := 0
240266
index := 1
241267
for node := list.head; node != nil; node = node.next {
242-
if node.value == value {
268+
if node.Value == value {
243269
count ++
244270
result = append(result, index)
245271
}
@@ -259,7 +285,7 @@ func (list *List) ChangeList(index int, value interface{}) error {
259285
return nil
260286
}
261287

262-
// 遍历输出切片
288+
// 遍历输出链表
263289
func (list *List) PrintList() {
264290
list.lock.Lock()
265291
defer list.lock.Unlock()
@@ -269,8 +295,27 @@ func (list *List) PrintList() {
269295
return
270296
}
271297
for node := list.head; node != nil; node = node.next {
272-
fmt.Printf("%v ", node.value)
298+
fmt.Printf("%v ", node.Value)
273299
}
274300
fmt.Println()
275301
}
276-
}
302+
}
303+
304+
// 对链表中的每个元素执行函数
305+
func (list *List) DoEach(f func(node ListNode)) {
306+
for node := list.head; node != nil; node = node.next {
307+
f(*node)
308+
}
309+
}
310+
311+
// 把链表中的每个元素放到一个切片里
312+
func (list *List) Items() []*interface{} {
313+
items := make([]*interface{}, list.length)
314+
for i, node := 0, list.head; node != nil; node = node.next {
315+
items[i] = &node.Value
316+
i ++
317+
}
318+
//fmt.Println(items)
319+
return items
320+
}
321+

Data_Structure/Link_List/main/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,5 @@ func main() {
132132
fmt.Println("Length is", testList.LenList())
133133
fmt.Println("isEmpty", testList.IsEmpty())
134134
}
135+
testList.Items()
135136
}

0 commit comments

Comments
 (0)