0%

資料結構-HashTable-refactor Insert Method

refactor 的部分在幹嘛?

最主要就是判斷傳入 insert function 的 key 值是否已存在 Hash Table 裡,
若有,就將傳入的值覆蓋掉那個 key 值所對應的 node 的值。
若沒有,就新增一個 node 到其所對應的 bucket 裡。

refactor 程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//...
HashTable.prototype.insert = function(key, value) {
const index = this.hash(key);
if(!this.buckets[index]) this.buckets[index] = new HashNode(key, value);
else if(this.buckets[index].key === key) this.buckets[index].value = value;
else {
let currentNode = this.buckets[index];
while(currentNode.next) {
if(currentNode.next.key === key) {
currentNode.next.value = value;
return;
}
currentNode = currentNode.next;
}
currentNode.next = new HashTable(key, value);
}
}

這邊解析一下上面的程式碼在幹嘛

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
// ...
HashTable.prototype.insert = function(key, value) {
const index = this.hash(key);
if(!this.buckets[index]) this.buckets[index] = new HashNode(key, value);

// 最主要是加了以下這個部分
// 如果此 bucket 的第一個元素的 key 等同於傳入的 key,那就更新這個元素的 value。
// 會需要為第一個元素單獨寫一個判斷是因為,後面的 while(currentNode.next) 的判斷,
// 永遠都在判斷 next 指向的元素,那就會漏掉第一個元素,因為沒有任何元素的 next 會指向第一個元素,
// 所以,才需要特別為第一個元素做判斷。
else if (this.buckets[index].key === key) {
this.buckets[index].value = value;
} else {
let currentNode = this.buckets[index];
while (currentNode.next) {
// 如果當前遍歷到的 node 的 next 指向的元素的 key 等同於傳入的 key,
// 那就更新 next 指向的元素的 value,並在更新完後,直接 return 結束遍歷。
if (currentNode.next.key === key) {
currentNode.next.value = value;
return;
}
currentNode = currentNode.next;
}
currentNode.next = new HashNode(key, value);
}
}

Take away

  • 在 update 的時候要特別先判斷該 bucket 的第一個元素的 key 是否就已經符合傳入的 key 了,因為 while(currentNode.next) 永遠只會遍歷到下一個 node,不會遍歷到第一個 node,所以,才需要對第一個元素做判斷。