diff --git a/codes/java/chapter_graph/graph_adjacency_list.java b/codes/java/chapter_graph/graph_adjacency_list.java index 417c84405..3e55b5468 100644 --- a/codes/java/chapter_graph/graph_adjacency_list.java +++ b/codes/java/chapter_graph/graph_adjacency_list.java @@ -1,5 +1,5 @@ /** - * File: graph_adjacency_matrix.java + * File: graph_adjacency_list.java * Created Time: 2023-01-26 * Author: Krahets (krahets@163.com) */ diff --git a/codes/javascript/chapter_graph/graph_adjacency_list.js b/codes/javascript/chapter_graph/graph_adjacency_list.js new file mode 100644 index 000000000..ed42819f2 --- /dev/null +++ b/codes/javascript/chapter_graph/graph_adjacency_list.js @@ -0,0 +1,121 @@ +/** + * File: graph_adjacency_list.js + * Created Time: 2023-02-09 + * Author: Justin (xiefahit@gmail.com) + */ + +/* 顶点类 */ +class Vertex { + val; + constructor(val) { + this.val = val; + } +} + +/* 基于邻接表实现的无向图类 */ +class GraphAdjList { + adjList; + /* 构造函数 */ + constructor(edges) { + this.adjList = new Map(); + // 添加所有顶点和边 + for (const edge of edges) { + this.addVertex(edge[0]); + this.addVertex(edge[1]); + this.addEdge(edge[0], edge[1]); + } + } + + /* 获取顶点数量 */ + size() { + return this.adjList.size; + } + + /* 添加边 */ + addEdge(vet1, vet2) { + if (!this.adjList.has(vet1) || !this.adjList.has(vet2) || vet1 === vet2) { + throw new Error("Illegal Argument Exception"); + } + // 添加边 vet1 - vet2 + this.adjList.get(vet1).add(vet2); + this.adjList.get(vet2).add(vet1); + } + + /* 删除边 */ + removeEdge(vet1, vet2) { + if (!this.adjList.has(vet1) || !this.adjList.has(vet2) || vet1 === vet2) { + throw new Error("Illegal Argument Exception"); + } + // 删除边 vet1 - vet2 + this.adjList.get(vet1).delete(vet2); + this.adjList.get(vet2).delete(vet1); + } + + /* 添加顶点 */ + addVertex(vet) { + if (this.adjList.has(vet)) return; + // 在邻接表中添加一个新链表(即 HashSet) + this.adjList.set(vet, new Set()); + } + + /* 删除顶点 */ + removeVertex(vet) { + if (!this.adjList.has(vet)) { + throw new Error("Illegal Argument Exception"); + } + // 在邻接表中删除顶点 vet 对应的链表(即 HashSet) + this.adjList.delete(vet); + // 遍历其它顶点的链表(即 HashSet),删除所有包含 vet 的边 + for (let set of this.adjList.values()) { + set.delete(vet); + } + } + + /* 打印邻接表 */ + print() { + console.log("邻接表 ="); + for (const [key, value] of this.adjList) { + const tmp = []; + for (const vertex of value){ + tmp.push(vertex.val); + } + console.log(key.val + ": " + tmp + ","); + } + } +} + +/* Driver Code */ +/* 初始化无向图 */ +const v0 = new Vertex(1), + v1 = new Vertex(3), + v2 = new Vertex(2), + v3 = new Vertex(5), + v4 = new Vertex(4); +const edges = [[v0, v1], [v1, v2], [v2, v3], [v0, v3], [v2, v4], [v3, v4]]; +const graph = new GraphAdjList(edges); +console.log("\n初始化后,图为"); +graph.print(); + +/* 添加边 */ +// 顶点 1, 2 即 v0, v2 +graph.addEdge(v0, v2); +console.log("\n添加边 1-2 后,图为"); +graph.print(); + +/* 删除边 */ +// 顶点 1, 3 即 v0, v1 +graph.removeEdge(v0, v1); +console.log("\n删除边 1-3 后,图为"); +graph.print(); + +/* 添加顶点 */ +const v5 = new Vertex(6); +graph.addVertex(v5); +console.log("\n添加顶点 6 后,图为"); +graph.print(); + +/* 删除顶点 */ +// 顶点 3 即 v1 +graph.removeVertex(v1); +console.log("\n删除顶点 3 后,图为"); +graph.print(); diff --git a/codes/typescript/chapter_graph/graph_adjacency_list.ts b/codes/typescript/chapter_graph/graph_adjacency_list.ts new file mode 100644 index 000000000..6ce41f8f8 --- /dev/null +++ b/codes/typescript/chapter_graph/graph_adjacency_list.ts @@ -0,0 +1,123 @@ +/** + * File: graph_adjacency_list.ts + * Created Time: 2023-02-09 + * Author: Justin (xiefahit@gmail.com) + */ + +/* 顶点类 */ +class Vertex { + val: number; + constructor(val: number) { + this.val = val; + } +} + +/* 基于邻接表实现的无向图类 */ +class GraphAdjList { + adjList: Map>; + /* 构造函数 */ + constructor(edges: Vertex[][]) { + this.adjList = new Map(); + // 添加所有顶点和边 + for (const edge of edges) { + this.addVertex(edge[0]); + this.addVertex(edge[1]); + this.addEdge(edge[0], edge[1]); + } + } + + /* 获取顶点数量 */ + size(): number { + return this.adjList.size; + } + + /* 添加边 */ + addEdge(vet1: Vertex, vet2: Vertex): void { + if (!this.adjList.has(vet1) || !this.adjList.has(vet2) || vet1 === vet2) { + throw new Error("Illegal Argument Exception"); + } + // 添加边 vet1 - vet2 + this.adjList.get(vet1).add(vet2); + this.adjList.get(vet2).add(vet1); + } + + /* 删除边 */ + removeEdge(vet1: Vertex, vet2: Vertex): void { + if (!this.adjList.has(vet1) || !this.adjList.has(vet2) || vet1 === vet2) { + throw new Error("Illegal Argument Exception"); + } + // 删除边 vet1 - vet2 + this.adjList.get(vet1).delete(vet2); + this.adjList.get(vet2).delete(vet1); + } + + /* 添加顶点 */ + addVertex(vet: Vertex): void { + if (this.adjList.has(vet)) return; + // 在邻接表中添加一个新链表(即 HashSet) + this.adjList.set(vet, new Set()); + } + + /* 删除顶点 */ + removeVertex(vet: Vertex): void { + if (!this.adjList.has(vet)) { + throw new Error("Illegal Argument Exception"); + } + // 在邻接表中删除顶点 vet 对应的链表(即 HashSet) + this.adjList.delete(vet); + // 遍历其它顶点的链表(即 HashSet),删除所有包含 vet 的边 + for (let set of this.adjList.values()) { + set.delete(vet); + } + } + + /* 打印邻接表 */ + print(): void { + console.log("邻接表 ="); + for (const [key, value] of this.adjList.entries()) { + const tmp = []; + for (const vertex of value){ + tmp.push(vertex.val); + } + console.log(key.val + ": " + tmp + ","); + } + } +} + +/* Driver Code */ +/* 初始化无向图 */ +const v0 = new Vertex(1), + v1 = new Vertex(3), + v2 = new Vertex(2), + v3 = new Vertex(5), + v4 = new Vertex(4); +const edges = [[v0, v1], [v1, v2], [v2, v3], [v0, v3], [v2, v4], [v3, v4]]; +const graph = new GraphAdjList(edges); +console.log("\n初始化后,图为"); +graph.print(); + +/* 添加边 */ +// 顶点 1, 2 即 v0, v2 +graph.addEdge(v0, v2); +console.log("\n添加边 1-2 后,图为"); +graph.print(); + +/* 删除边 */ +// 顶点 1, 3 即 v0, v1 +graph.removeEdge(v0, v1); +console.log("\n删除边 1-3 后,图为"); +graph.print(); + +/* 添加顶点 */ +const v5 = new Vertex(6); +graph.addVertex(v5); +console.log("\n添加顶点 6 后,图为"); +graph.print(); + +/* 删除顶点 */ +// 顶点 3 即 v1 +graph.removeVertex(v1); +console.log("\n删除顶点 3 后,图为"); +graph.print(); + +export {}