定义
图是一种数据结构,由一组节点或顶点以及一组表示这些节点之间连接的边组成。
图可以是有向的或无向的,而它们的边可以分配数字代表权重。
图数据结构中的每个节点都必须具有以下属性:
- key: 节点的键
- value: 节点的值
图数据结构中的每条边都必须具有以下属性:
-
a: 边的起始节点
-
b: 边的目标节点
-
weight:边缘
图数据结构的主要操作是:
- addNode:插入具有特定键和值的新节点
- addEdge:在两个给定节点之间插入一条新边,可选择设置其权重
- removeNode:删除具有指定键的节点
- removeEdge:删除两个给定节点之间的边
- findNode:检索具有给定键的节点
- hasEdge: 检查图在两个给定节点之间是否有边
- setEdgeWeight: 设置给定边的权重
- getEdgeWeight: 获取给定边的权重
- adjacent:从给定节点查找存在边的所有节点
- indegree:计算给定节点的总边数
- outdegree:
class Graph {
constructor(directed = true) {
this.directed = directed;
this.nodes = [];
this.edges = new Map();
}
addNode(key, value = key) {
this.nodes.push({ key, value });
}
addEdge(a, b, weight) {
this.edges.set(JSON.stringify([a, b]), { a, b, weight });
if (!this.directed)
this.edges.set(JSON.stringify([b, a]), { a: b, b: a, weight });
}
removeNode(key) {
this.nodes = this.nodes.filter(n => n.key !== key);
[...this.edges.values()].forEach(({ a, b }) => {
if (a === key || b === key) this.edges.delete(JSON.stringify([a, b]));
});
}
removeEdge(a, b) {
this.edges.delete(JSON.stringify([a, b]));
if (!this.directed) this.edges.delete(JSON.stringify([b, a]));
}
findNode(key) {
return this.nodes.find(x => x.key === key);
}
hasEdge(a, b) {
return this.edges.has(JSON.stringify([a, b]));
}
setEdgeWeight(a, b, weight) {
this.edges.set(JSON.stringify([a, b]), { a, b, weight });
if (!this.directed)
this.edges.set(JSON.stringify([b, a]), { a: b, b: a, weight });
}
getEdgeWeight(a, b) {
return this.edges.get(JSON.stringify([a, b])).weight;
}
adjacent(key) {
return [...this.edges.values()].reduce((acc, { a, b }) => {
if (a === key) acc.push(b);
return acc;
}, []);
}
indegree(key) {
return [...this.edges.values()].reduce((acc, { a, b }) => {
if (b === key) acc++;
return acc;
}, 0);
}
outdegree(key) {
return [...this.edges.values()].reduce((acc, { a, b }) => {
if (a === key) acc++;
return acc;
}, 0);
}
}
- class使用 a为每个实例constructor初始化一个空数组 ,nodes和 a Map,创建 a 。edges可选参数directed指定图是否有向。
- 定义一个addNode()方法,用于Array.prototype.push()在nodes数组中添加一个新节点。
- 定义一个addEdge()方法,用于Map.prototype.set()向edgesMap 添加新边,JSON.stringify()用于生成唯一键。
- 定义一个removeNode()方法,该方法使用Array.prototype.filter()和Map.prototype.delete()删除给定的节点和任何连接到它的边。
- 定义一个removeEdge()方法,用于Map.prototype.delete()移除给定的边。
- 定义一个findNode()方法,用于Array.prototype.find()返回给定节点(如果有)。
- 定义一个hasEdge()方法,该方法使用Map.prototype.has()和JSON.stringify()检查给定的边是否存在于edges地图中。
- 定义一个setEdgeWeight()方法,用于Map.prototype.set()设置适当边的权重,其密钥由 生成JSON.stringify()。
- 定义一个getEdgeWeight()方法,用于Map.prototype.get()获取相应边的 8 个,其密钥由 生成JSON.stringify()。
- 定义一个adjacent()方法,该方法使用和Map.prototype.values()查找连接到给定节点的所有节点。Array.prototype.reduce()Array.prototype.push()
- 定义一个indegree()方法,该方法使用Map.prototype.values()和Array.prototype.reduce()计算给定节点的边数。
- 定义一个outdegree()方法,该方法使用Map.prototype.values()和Array.prototype.reduce()计算给定节点的边数
const g = new Graph();
g.addNode('a');
g.addNode('b');
g.addNode('c');
g.addNode('d');
g.addEdge('a', 'c');
g.addEdge('b', 'c');
g.addEdge('c', 'b');
g.addEdge('d', 'a');
g.nodes.map(x => x.value); // ['a', 'b', 'c', 'd']
[...g.edges.values()].map(({ a, b }) => `${a} => ${b}`);
// ['a => c', 'b => c', 'c => b', 'd => a']
g.adjacent('c'); // ['b']
g.indegree('c'); // 2
g.outdegree('c'); // 1
g.hasEdge('d', 'a'); // true
g.hasEdge('a', 'd'); // false
g.removeEdge('c', 'b');
[...g.edges.values()].map(({ a, b }) => `${a} => ${b}`);
// ['a => c', 'b => c', 'd => a']
g.removeNode('c');
g.nodes.map(x => x.value); // ['a', 'b', 'd']
[...g.edges.values()].map(({ a, b }) => `${a} => ${b}`);
// ['d => a']
g.setEdgeWeight('d', 'a', 5);
g.getEdgeWeight('d', 'a'); // 5