From 2d421de984f68a7e0ad24f655bb68130f9a48914 Mon Sep 17 00:00:00 2001 From: zhuoqinyue <64182179+zhuoqinyue@users.noreply.github.com> Date: Fri, 24 Feb 2023 11:11:11 -0600 Subject: [PATCH] feat: add bfs and dfs for JS and TS (#377) * add bfs and dfs for JS and TS * update the type * Apply suggestions from code review Co-authored-by: Justin Tse * Update graph_dfs.ts * Update graph_bfs.ts * Update graph_dfs.ts * Update graph_bfs.ts * Update graph_dfs.js * Update graph_bfs.js --------- Co-authored-by: steak-zhuo Co-authored-by: Yudong Jin Co-authored-by: Justin Tse --- codes/javascript/chapter_graph/graph_bfs.js | 54 +++++++++++++++++++++ codes/javascript/chapter_graph/graph_dfs.js | 50 +++++++++++++++++++ codes/typescript/chapter_graph/graph_bfs.ts | 52 ++++++++++++++++++++ codes/typescript/chapter_graph/graph_dfs.ts | 49 +++++++++++++++++++ 4 files changed, 205 insertions(+) create mode 100644 codes/javascript/chapter_graph/graph_bfs.js create mode 100644 codes/javascript/chapter_graph/graph_dfs.js create mode 100644 codes/typescript/chapter_graph/graph_bfs.ts create mode 100644 codes/typescript/chapter_graph/graph_dfs.ts diff --git a/codes/javascript/chapter_graph/graph_bfs.js b/codes/javascript/chapter_graph/graph_bfs.js new file mode 100644 index 000000000..092a5f8cf --- /dev/null +++ b/codes/javascript/chapter_graph/graph_bfs.js @@ -0,0 +1,54 @@ +/** + * File: graph_bfs.js + * Created Time: 2023-02-21 + * Author: Zhuo Qinyue (1403450829@qq.com) + */ + + +const { GraphAdjList } = require('./graph_adjacency_list'); +const { Vertex } = require('../include/Vertex'); + + +/* 广度优先遍历 BFS */ +// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 +const graphBfs = (graph, startVet) => { + // 顶点遍历序列 + const res = []; + // 哈希表,用于记录已被访问过的顶点 + const visited = new Set(); + visited.add(startVet); + // 队列用于实现 BFS + const que = [startVet]; + + // 以顶点 vet 为起点,循环直至访问完所有顶点 + while (que.length) { + const vet = que.shift(); // 队首顶点出队 + res.push(vet); // 记录访问顶点 + // 遍历该顶点的所有邻接顶点 + for (const adjVet of graph.adjList.get(vet) ?? []) { + if (visited.has(adjVet)) { + continue; // 跳过已被访问过的顶点 + } + que.push(adjVet); // 只入队未访问的顶点 + visited.add(adjVet); // 标记该顶点已被访问 + } + } + // 返回顶点遍历序列 + return res; +} + + +/* Driver Code */ +/* 初始化无向图 */ +const v = Vertex.valsToVets([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); +const edges = [[v[0], v[1]], [v[0], v[3]], [v[1], v[2]], [v[1], v[4]], +[v[2], v[5]], [v[3], v[4]], [v[3], v[6]], [v[4], v[5]], +[v[4], v[7]], [v[5], v[8]], [v[6], v[7]], [v[7], v[8]]]; +const graph = new GraphAdjList(edges); +console.log("\n初始化后,图为"); +graph.print(); + +/* 广度优先遍历 BFS */ +const res = graphBfs(graph, v[0]); +console.log("\n广度优先遍历(BFS)顶点序列为"); +console.log(Vertex.vetsToVals(res)); diff --git a/codes/javascript/chapter_graph/graph_dfs.js b/codes/javascript/chapter_graph/graph_dfs.js new file mode 100644 index 000000000..30439902e --- /dev/null +++ b/codes/javascript/chapter_graph/graph_dfs.js @@ -0,0 +1,50 @@ +/** + * File: graph_dfs.js + * Created Time: 2023-02-21 + * Author: Zhuo Qinyue (1403450829@qq.com) + */ + + +const { Vertex } = require('../include/Vertex'); +const { GraphAdjList } = require('./graph_adjacency_list'); + +/* 深度优先遍历 DFS */ +// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 +const dfs = (graph, visited, res, vet) => { + res.push(vet); // 记录访问顶点 + visited.add(vet); // 标记该顶点已被访问 + // 遍历该顶点的所有邻接顶点 + for (const adjVet of graph.adjList.get(vet)) { + if (visited.has(adjVet)) { + continue; // 跳过已被访问过的顶点 + } + // 递归访问邻接顶点 + dfs(graph, visited, res, adjVet); + } +} + +/* 深度优先遍历 DFS */ +// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 +const graphDFS = (graph, startVet) => { + // 顶点遍历序列 + const res = []; + // 哈希表,用于记录已被访问过的顶点 + const visited = new Set(); + dfs(graph, visited, res, startVet); + return res; +} + + +/* Driver Code */ +/* 初始化无向图 */ +const v = Vertex.valsToVets([0, 1, 2, 3, 4, 5, 6]); +const edges = [[v[0], v[1]], [v[0], v[3]], [v[1], v[2]], +[v[2], v[5]], [v[4], v[5]], [v[5], v[6]]]; +const graph = new GraphAdjList(edges); +console.log("\n初始化后,图为"); +graph.print(); + +/* 深度优先遍历 DFS */ +const res = graphDFS(graph, v[0]); +console.log("\n深度优先遍历(DFS)顶点序列为"); +console.log(Vertex.vetsToVals(res)); diff --git a/codes/typescript/chapter_graph/graph_bfs.ts b/codes/typescript/chapter_graph/graph_bfs.ts new file mode 100644 index 000000000..48e2a615b --- /dev/null +++ b/codes/typescript/chapter_graph/graph_bfs.ts @@ -0,0 +1,52 @@ +/** + * File: graph_bfs.ts + * Created Time: 2023-02-21 + * Author: Zhuo Qinyue (1403450829@qq.com) + */ + + +import { GraphAdjList } from './graph_adjacency_list' +import { Vertex } from '../module/Vertex'; + +/* 广度优先遍历 BFS */ +// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 +const graphBfs = (graph: GraphAdjList, startVet: Vertex): Vertex[] => { + // 顶点遍历序列 + const res: Vertex[] = []; + // 哈希表,用于记录已被访问过的顶点 + const visited: Set = new Set(); + visited.add(startVet); + // 队列用于实现 BFS + const que = [startVet]; + // 以顶点 vet 为起点,循环直至访问完所有顶点 + while (que.length) { + const vet = que.shift(); // 队首顶点出队 + res.push(vet); // 记录访问顶点 + // 遍历该顶点的所有邻接顶点 + for (const adjVet of graph.adjList.get(vet) ?? []) { + if (visited.has(adjVet)) { + continue; // 跳过已被访问过的顶点 + } + que.push(adjVet); // 只入队未访问 + visited.add(adjVet); // 标记该顶点已被访问 + } + } + // 返回顶点遍历序列 + return res; +} + + +/* Driver Code */ +/* 初始化无向图 */ +const v = Vertex.valsToVets([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); +const edges = [[v[0], v[1]], [v[0], v[3]], [v[1], v[2]], [v[1], v[4]], + [v[2], v[5]], [v[3], v[4]], [v[3], v[6]], [v[4], v[5]], + [v[4], v[7]], [v[5], v[8]], [v[6], v[7]], [v[7], v[8]]]; +const graph = new GraphAdjList(edges); +console.log("\n初始化后,图为"); +graph.print(); + +/* 广度优先遍历 BFS */ +const res = graphBfs(graph, v[0]); +console.log("\n广度优先遍历(BFS)顶点序列为"); +console.log(Vertex.vetsToVals(res)); diff --git a/codes/typescript/chapter_graph/graph_dfs.ts b/codes/typescript/chapter_graph/graph_dfs.ts new file mode 100644 index 000000000..9a4786f5e --- /dev/null +++ b/codes/typescript/chapter_graph/graph_dfs.ts @@ -0,0 +1,49 @@ +/** + * File: graph_dfs.ts + * Created Time: 2023-02-21 + * Author: Zhuo Qinyue (1403450829@qq.com) + */ + + +import { Vertex } from '../module/Vertex'; +import { GraphAdjList } from './graph_adjacency_list'; + +/* 深度优先遍历 DFS 辅助函数 */ +const dfs = (graph: GraphAdjList, visited: Set, res: Vertex[], vet: Vertex): void => { + res.push(vet); // 记录访问顶点 + visited.add(vet); // 标记该顶点已被访问 + // 遍历该顶点的所有邻接顶点 + for (const adjVet of graph.adjList.get(vet)) { + if (visited.has(adjVet)) { + continue; // 跳过已被访问过的顶点 + } + // 递归访问邻接顶点 + dfs(graph, visited, res, adjVet); + } +} + +/* 深度优先遍历 DFS */ +// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 +const graphDFS = (graph: GraphAdjList, startVet: Vertex): Vertex[] => { + // 顶点遍历序列 + const res: Vertex[] = []; + // 哈希表,用于记录已被访问过的顶点 + const visited: Set = new Set(); + dfs(graph, visited, res, startVet); + return res; +} + + +/* Driver Code */ +/* 初始化无向图 */ +const v = Vertex.valsToVets([0, 1, 2, 3, 4, 5, 6]); +const edges = [[v[0], v[1]], [v[0], v[3]], [v[1], v[2]], + [v[2], v[5]], [v[4], v[5]], [v[5], v[6]]]; +const graph = new GraphAdjList(edges); +console.log("\n初始化后,图为"); +graph.print(); + +/* 深度优先遍历 DFS */ +const res = graphDFS(graph, v[0]); +console.log("\n深度优先遍历(DFS)顶点序列为"); +console.log(Vertex.vetsToVals(res));