最佳邻接表实现
Best Adjacency List Implementation
我可以将邻接表实现为链表的 Array,或链表的 Map(即哈希 Table)。是否有理由在 Map 实现上使用 Array 实现?我问是因为我遇到过很多描述 Array 实现的网站,但很少提到使用 Hash Tables。据我了解,HashTables 应该优于 Arrays.
下面是我将如何编写基于哈希 Table 的邻接列表以及助手 类.
的相关代码
LinkedListNode.js
class LinkedListNode {
constructor(value = 0, next = undefined) {
this.value = value;
this.next = next;
}
}
LinkedList.js(删除了不必要的功能)
class LinkedList {
constructor(headValue = null) {
this.head = headValue ? new LinkedListNode(headValue) : headValue;
}
addToTail(value) {
const node = new LinkedListNode(value);
if (!this.head) {
this.head = node;
} else {
let pointer = this.head;
while (pointer.next) {
pointer = pointer.next;
}
pointer.next = node;
}
}
toArray() {
const items = [];
let pointer = this.head;
while (pointer) {
items.push(pointer.value);
pointer = pointer.next;
}
return items;
}
}
HashTable.js - 我们假设没有碰撞
class HashTable {
constructor() {
this.items = {};
}
set(key, value) {
if (this.items[key]) {
this.items[key].addToTail(value);
} else {
this.items[key] = new LinkedList(value);
}
};
get(key) {
return this.items[key];
}
print() {
const entries = Object.entries(this.items);
for (let i = 0; i < entries.length; i += 1) {
const [key, list] = entries[i];
console.log(`${key}: ${list.toArray()}`);
}
}
}
用法
const adjacencyList = new HashTable();
adjacencyList.set(1, 2);
adjacencyList.set(2, 4);
adjacencyList.set(3, 1);
adjacencyList.set(3, 2);
adjacencyList.set(3, 5);
adjacencyList.set(4, 6);
adjacencyList.set(5, 2);
adjacencyList.set(5, 4);
adjacencyList.set(5, 6);
adjacencyList.set(6, null);
adjacencyList.print();
// Outputs
'1: 2'
'2: 4'
'3: 1,2,5'
'4: 6'
'5: 2,4,6'
'6: '
Is there ever a reason to use the Array implementation over the Map implementation?
是:
- 当你知道你的图有 n 个节点数,并且
- 节点由 0..n-1
范围内的整数标识
在这种情况下,“散列”是数组中的索引。当您使用数组而不是普通对象时,某些 JavaScript 引擎可能会生成更快的代码。
注意:如果将链表替换为数组(和push
)肯定会更快。
我可以将邻接表实现为链表的 Array,或链表的 Map(即哈希 Table)。是否有理由在 Map 实现上使用 Array 实现?我问是因为我遇到过很多描述 Array 实现的网站,但很少提到使用 Hash Tables。据我了解,HashTables 应该优于 Arrays.
下面是我将如何编写基于哈希 Table 的邻接列表以及助手 类.
的相关代码LinkedListNode.js
class LinkedListNode {
constructor(value = 0, next = undefined) {
this.value = value;
this.next = next;
}
}
LinkedList.js(删除了不必要的功能)
class LinkedList {
constructor(headValue = null) {
this.head = headValue ? new LinkedListNode(headValue) : headValue;
}
addToTail(value) {
const node = new LinkedListNode(value);
if (!this.head) {
this.head = node;
} else {
let pointer = this.head;
while (pointer.next) {
pointer = pointer.next;
}
pointer.next = node;
}
}
toArray() {
const items = [];
let pointer = this.head;
while (pointer) {
items.push(pointer.value);
pointer = pointer.next;
}
return items;
}
}
HashTable.js - 我们假设没有碰撞
class HashTable {
constructor() {
this.items = {};
}
set(key, value) {
if (this.items[key]) {
this.items[key].addToTail(value);
} else {
this.items[key] = new LinkedList(value);
}
};
get(key) {
return this.items[key];
}
print() {
const entries = Object.entries(this.items);
for (let i = 0; i < entries.length; i += 1) {
const [key, list] = entries[i];
console.log(`${key}: ${list.toArray()}`);
}
}
}
用法
const adjacencyList = new HashTable();
adjacencyList.set(1, 2);
adjacencyList.set(2, 4);
adjacencyList.set(3, 1);
adjacencyList.set(3, 2);
adjacencyList.set(3, 5);
adjacencyList.set(4, 6);
adjacencyList.set(5, 2);
adjacencyList.set(5, 4);
adjacencyList.set(5, 6);
adjacencyList.set(6, null);
adjacencyList.print();
// Outputs
'1: 2'
'2: 4'
'3: 1,2,5'
'4: 6'
'5: 2,4,6'
'6: '
Is there ever a reason to use the Array implementation over the Map implementation?
是:
- 当你知道你的图有 n 个节点数,并且
- 节点由 0..n-1 范围内的整数标识
在这种情况下,“散列”是数组中的索引。当您使用数组而不是普通对象时,某些 JavaScript 引擎可能会生成更快的代码。
注意:如果将链表替换为数组(和push
)肯定会更快。