-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhashtable.js
More file actions
191 lines (161 loc) · 4.85 KB
/
hashtable.js
File metadata and controls
191 lines (161 loc) · 4.85 KB
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
var LinkedList = require('./LinkedList') // 分离链接法需要引入之前定义的链表
function HashTable () {
var table = []
var loseloseHashCode = function (key) {
var hash = 0
for (var i = 0; i < key.length; i++) {
hash += key.charCodeAt(i)
}
// 37是一个任意的数,这里只是为了得到一个较小的数值
return hash % 37
}
// 通过链表存储的是一个包含键值的对象
var ValuePair = function (key, value) {
this.key = key
this.value = value
// 重写toString主要是方便输出查看
this.toString = function () {
return '[' + this.key + ' - ' + this.value + ']'
}
}
// 初始实现的三种方法
// this.put = function (key, value) {
// var position = loseloseHashCode(key)
// // 用于展示的
// console.log(position + ' - ' + key)
// table[position] = value
// }
// this.get = function (key) {
// return table[loseloseHashCode(key)]
// }
// this.remove = function (key) {
// table[loseloseHashCode(key)] = undefined
// }
// 为了解决冲突,使用分离链接法重写
this.put = function (key, value) {
var position = loseloseHashCode(key)
if (table[position] === undefined) {
table[position] = new LinkedList()
}
table[position].append(new ValuePair(key, value))
}
this.get = function (key) {
var position = loseloseHashCode(key)
if (table[position] !== undefined) {
var current = table[position].getHead()
// 遍历链表查找值
while (current.next) {
if (current.element.key === key) {
return current.element.value
}
current = current.next
}
// 检查元素如果是最后一个的情况
if (current.element.key === key) {
return current.element.value
}
}
return undefined
}
this.remove = function (key) {
var position = loseloseHashCode(key)
if (table[position] !== undefined) {
var current = table[position].getHead()
// 遍历查找值
while (current.next) {
if (current.element.key === key) {
// 使用链表的remove方法
table[position].remove(current.element)
// 当链表为空了,就把散列表该位置设为undefined
if (table[position].isEmpty()) {
table[position] = undefined
}
return true
}
current = current.next
}
if (current.element.key === key) {
table[position].remove(current.element)
if (table[position].isEmpty()) {
table[position] = undefined
}
return true
}
}
return false
}
// 使用线性探查重写
this.put = function (key, value) {
var position = loseloseHashCode(key)
// 如果当前位置是空,就直接赋值
if (table[position] === undefined) {
table[position] === new ValuePair(key, value)
} else {
// 否则就在下一个索引赋值
var index = ++position
while (table[index] !== undefined) {
index++
}
table[index] = new ValuePair(key, value)
}
}
this.get = function (key) {
var position = loseloseHashCode(key)
if (table[position] !== undefined) {
if (table[position].key === key) {
return table[position].value
} else {
var index = ++position
while(table[index].key !== key || table[index] === undefined) {
index++
}
if (table[index].key === key) {
return table[position].value
}
}
}
return undefined
}
this.remove = function () {
var position = loseloseHashCode(key)
if (table[position] !== undefined) {
if (table[position].key === key) {
table[position] = undefined
} else {
var index = ++position
while(table[index].key !== key || table[index] === undefined) {
index++
}
if (table[index].key === key) {
table[position] = undefined
}
}
}
return undefined
}
// 用来输出整个散列表,查看结果用的
this.print = function () {
for (var i = 0; i < table.length; i++) {
if (table[i] !== undefined) {
console.log(i + ': ' + table[i])
}
}
}
}
var hash = new HashTable()
hash.put('Gandalf', 'gandalf@email.com')
hash.put('John', 'john@email.com')
hash.put('Tyrion', 'tyrion@email.com')
hash.put('Aaron', 'aaron@email.com')
hash.put('Donnie', 'donnie@email.com')
hash.put('Ana', 'ana@email.com')
hash.put('Jonathan', 'jonathan@email.com')
hash.put('Jamie', 'jamie@email.com')
hash.put('Sue', 'sue@email.com')
hash.put('Mindy', 'mindy@email.com')
hash.put('Paul', 'paul@email.com')
hash.put('Nathan', 'nathan@email.com')
/*
* 上面Jonathan, Jamie, Sue散列值相同,因此被添加时,后面的值会覆盖前面的值,其他冲突元素也一样。
*/
hash.print()