小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
图的分类
有向图
无向图
有权重图
有了之前树的深度优先遍历和广度优先遍历的基础。今天要介绍图深度优先遍历有容易多了,比较类似,对于深度优先通常用栈,对于广度优先通常用到队列。
我们构建以一个图,用邻边对应到一个结点
const graph = {
a:['c','b'],
b:['d'],
c:['e'],
d:['f'],
e:[],
f:[]
}
创建一个栈(stack),然后将以结点压入到栈中。
然后判断是否栈是否为空,将栈顶的结点出栈后,同时将结点的邻居结点压入到栈,然后进入下一次迭代
每一次迭代,判断是否栈为空,如果为空就退出迭代,不为空这先将栈顶的结点出栈,然后在将该结点的邻接结点压入到栈,重复以上的迭代。
深度优先遍历
迭代方式
const depthFirstPrint = (graph,source)=>{
const stack = [source];
while(stack.length > 0){
const current = stack.pop();
console.log(current)
for(let neighboer of graph[current]){
stack.push(neighboer)
}
}
}
const graph = {
a:['c','b'],
b:['d'],
c:['e'],
d:['f'],
e:[],
f:[]
}
depthFirstPrint(graph,'a');
递归方式
const depthFirstPrintWithRecursive = (graph, source) => {
console.log(source);
for( let neighbor of graph[source]){
depthFirstPrintWithRecursive(graph,neighbor)
}
}
const graph = {
a:['b','c'],
b:['d'],
c:['e'],
d:['f'],
e:[],
f:[]
}
depthFirstPrintWithRecursive(graph,'a');
广度优先遍历
迭代方式
const breathFirstPrint = (graph,source)=>{
const queue = [ source ];
while(queue.length > 0){
const current = queue.shift();
console.log(current);
for(let neighbor of graph[current]){
queue.push(neighbor)
}
}
}
const graph = {
a:['c','b'],
b:['d'],
c:['e'],
d:['f'],
e:[],
f:[]
}
breathFirstPrint(graph,'a');