现有一张图
宽度优先遍历的顺序可以是
1 2 3 4 5
我们创建一个队列和已打印节点map
把1放进去,打印1,标记1已打印
然后进入循环,直到队列为空
从队列中弹出1,判断1的next 2 3 4 有没有打印过,没有打印过,就打印 2 3 4 ,并标记2 3 4 已打印
弹出2,判断2 的next 3 5有没有打印过,3打印过就跳过,5没打印过就打印5,将5放进队列
以此类推
func bts(node *Node) {
if node == nil {
return
}
print := make(map[*Node]struct{})
queue := make([]*Node, 0)
queue = append(queue, node)
print[node] = struct{}{}
for len(queue) != 0 {
//队列弹出一个值
cur := queue[0]
queue = queue[1:]
//将它的所有next放进去队列
for _, next := range cur.Next {
if _, exist := print[next]; !exist {
queue = append(queue, next)
//打印该值
fmt.Println(cur.value)
//沉没该值
print[cur] = struct{}{}
}
}
}
}
深度优先遍历的顺序可以是1 2 3 5 4 (一条路走到黑)
我们创建一个栈(先进后出),和一个已打印节点的map
第一步将1节点放进去,打印1,标记已打印
进入循环,直到栈为空
弹出1,获取1的next 2 3 4,2如果未被标记过,打印2,标记2,并将当前节点1和2再压进栈中,退出子循环(不处理3 和4)
弹出2,获取2的next 3 5 ,3 如果未被标记过,打印3, 标记3,并将当前节点2和3再压进栈中,退出子循环(不处理5)
弹出3,获取3的next5 ,5 如果未被标记过,打印5, 标记5,并将当前节点3和5再压进栈中
弹出5,5没有next,不处理
弹出3,3的next5已经标记过,不处理
弹出2,2的next3 5 已经标记过,不处理
弹出1,1的next 2 3 4 ,23不处理,打印4,标记4,将当前节点1和4再压进栈
弹出4,4没有next不处理
弹出1,1的next都被标记过不处理
栈空退出循环
func dfs(node *Node) {
if node == nil {
return
}
stack := make([]*Node, 0)
print := make(map[*Node]struct{})
stack = append(stack, node)
print[node] = struct{}{}
fmt.Println(node.value)
for len(stack) != 0 {
cur := stack[len(stack)-1]
stack = stack[:len(stack)-1]
for _, next := range cur.Next {
if _, exist := print[next]; !exist {
stack = append(stack, cur)
stack = append(stack, next)
print[next] = struct{}{}
fmt.Println(next.value)
break
}
}
}
}
现在有个项目1需要编译,但是它依赖项目2 3 4 ,同时要编译2就要先编译5,我们如何找到正确的编译顺序呢?
这里用到拓扑排序
新建一个队列queue,将所有入度为0的点放入队列
进入循环直到队列为空
弹出5,编译5,再把5和5的next边擦掉
擦掉后2的入度为0了,将2放入队列
弹出4,编译4,再把4和4的next边擦掉
弹出2,编译2,再把2和2的next边擦掉
擦掉后,3的入度为0,将3放入队列
弹出3,编译3,再把3和3的next边擦掉
擦掉后,1的入度为0,将1放入队列
弹出1,编译1,队列为空退出循环
func sortedTopology(graph Graph){
inMap:=make(map[*Node]int)
//准备入度为0的队列
queue:=make([]*Node,0)
for _,node:=range graph.nodes{
inMap[node]=node.in
if node.in==0{
queue= append(queue, node)
}
}
for len(queue)!=0{
cur:=queue[0]
queue=queue[1:]
//编译cur
fmt.Println(cur.value)
for _,next:=range cur.Next{
inMap[next]=inMap[next]-1
if inMap[next]==0{
queue= append(queue, next)
}
}
}
}