小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
图是由具有边的节点集合组成的数据结构,图可以是定向的或者是不定向的。图具有以下几种基本元素:
- 节点:Node
- 边:Edge
- |V|:图中顶点的总数
- |E|:图中的连接总数
主要实现一个有向图 Graph 类:
class Graph{
constructor() {
// 使用map表述图中顶点关系
this.AdjList = new Map()
}
}
先通过创建节点来创建一个图:
let graph = new Graph()
graph.addVertex('A')
graph.addVertex('B')
graph.addVertex('C')
graph.addVertex('D')
添加顶点 addVertex
addVertex(vertex) {
if(!this.AdjList.has(vertex)) {
this.AdjList.set(vertex, [])
} else {
throw new Error('该顶点已存在!')
}
}
此时,A、B、C、D顶点都对应一个数组:
'A' -> []
'B' -> []
'C' -> []
'D' -> []
数组将用来存储边,预计得到如下关系:
'A' -> ['B', 'C', 'D']
'B' -> []
'C' -> ['B']
'D' -> ['C']
添加边 addEdge
addEdge(vertex, node) {
if(this.AdjList.has(vertex)) {
if(this.AdjList.has(node)) {
let arr = this.AdjList.get(vertex)
if(!arr.includes(node)) {
arr.push(node)
}
} else {
throw new Error('不能添加')
}
} else {
throw new Error(`请先添加顶点${vertex}`)
}
}
打印图 print
print() {
// 使用 for of 遍历并打印 this.AdjList
for (let [key, value] of this.AdjList) {
console.log(key, value)
}
}
广度优先遍历 BFS
createVisitedObject() {
let map = {}
for (let key of this.AdjList.keys()) {
arr[key] = false
}
return map
}
bfs (initialNode) {
// 创建一个已访问节点的 map
let visited = this.createVisitedObject()
// 模拟一个队列
let queue = []
// 第一个节点已访问
visited[initialNode] = true
// 第一个节点入队列
queue.push(initialNode)
while (queue.length) {
let current = queue.shift()
console.log(current)
// 获得该节点的其他节点关系
let arr = this.AdjList.get(current)
for (let elem of arr) {
// 如果当前节点没有访问过
if (!visited[elem]) {
visited[elem] = true
queue.push(elem)
}
}
}
}
BFS-利用队列实现的搜索算法,实现步骤:
- 起始节点作为起始,并初始化一个空对象——visited;
- 初始化一个空数组,该数组将模拟一个队列;
- 将起始节点标记为已访问;
- 将起始节点放入队列中;
- 循环直到队列为空。
深度优先 DFS
createVisitedObject() {
let map = {}
for (let key of this.AdjList.keys()) {
arr[key] = false
}
return map
}
// 深度优先算法
dfs(initialNode) {
let visited = this.createVisitedObject()
this.dfsHelper(initialNode, visited)
}
dfsHelper(node, visited) {
visited[node] = true
console.log(node)
let arr = this.AdjList.get(node)
// 遍历节点调用 this.dfsHelper
for (let elem of arr) {
if (!visited[elem]) {
this.dfsHelper(elem, visited)
}
}
}
DFS-利用递归实现的搜索算法,实现步骤:
- 起始节点作为起始,创建访问对象;
- 调用辅助函数递归起始节点。
最后说一句
如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下,您的支持是我坚持写作最大的动力,多谢支持。