BFS解迷宫问题(Go实现)
改了现有的C++代码而来的,所以说实话并不满意。
广度优先搜索(又称广度优先搜索,简称BFS,以下简称广度搜索)是连通图的遍历策略。它之所以被命名是因为它的思想从一个顶点V0开始,并在其周围的一个广域范围内径向传播。最直观的经典例子之一就是在迷宫中行走。我们从头开始,寻找到终点的最短路径。许多最短路径算法都是基于广度优先的思想。
染色法解题:
初始节点均为白色。起点变为灰色并加入队列Q。重复以下操作:
将灰色节点染黑,将四周节点染灰并加入队列,直至给终点染色。
此时可得路径。
package main import "fmt" var ( map1 [][]int // 地图 hasPassedArea [][]int // 通过的地方 为0表示未通过 n, m int // 地图长宽 sq SQQueue // 队列表示的路径 ) type Node struct { X, Y, LastX, LastY int // 坐标及上一个节点坐标 } type SQQueue struct // 队列 { Base [99]Node Front, Rear int } func FindPath(x, y int) { for sq.Front != sq.Rear { // 若没走到一开始的位置 now := sq.Base[sq.Front] // 当前位置 sq.Front++ if now.X == n - 1 && now.Y == m - 1 { // 若到达终点 pathLength := 0 // 路径长度 var path [99]Node // 路径 path[pathLength] = now pathLength++ i := sq.Front - 2 // 计算长度 for now.LastX != -1 { for ; i >= 0; i-- { if sq.Base[i].X == now.LastX && sq.Base[i].Y == now.LastY { now = sq.Base[i] path[pathLength] = now pathLength++ break } } } fmt.Print("最短路径为:") for i = pathLength - 1; i >= 0; i-- { if i < pathLength - 1 { fmt.Print("->") } fmt.Print("(", path[i].X, ",", path[i].Y, ")") } fmt.Println() return } // 若没有到达终点 // 尝试向当前节点的四周染色 if now.X + 1 < n && map1[now.X + 1][now.Y] != 0 && hasPassedArea[now.X + 1][now.Y] == 0 { // 向右 hasPassedArea[now.X + 1][now.Y] = 1 var newNode Node newNode.LastX, newNode.LastY, newNode.X, newNode.Y = now.X, now.Y, now.X + 1, now.Y sq.Base[sq.Rear] = newNode sq.Rear++ } if now.X - 1 >= 0 && map1[now.X - 1][now.Y] != 0 && hasPassedArea[now.X - 1][now.Y] == 0 { // 向左 hasPassedArea[now.X - 1][now.Y] = 1 var newNode Node newNode.LastX, newNode.LastY, newNode.X, newNode.Y = now.X, now.Y, now.X - 1, now.Y sq.Base[sq.Rear] = newNode sq.Rear++ } if now.Y + 1 < m && map1[now.X][now.Y + 1] != 0 && hasPassedArea[now.X][now.Y + 1] == 0 { // 向下 hasPassedArea[now.X][now.Y + 1] = 1 var newNode Node newNode.LastX, newNode.LastY, newNode.X, newNode.Y = now.X, now.Y, now.X, now.Y + 1 sq.Base[sq.Rear] = newNode sq.Rear++ } if now.Y - 1 >= 0 && map1[now.X][now.Y - 1] != 0 && hasPassedArea[now.X][now.Y - 1] == 0{ // 向上 hasPassedArea[now.X][now.Y - 1] = 1 var newNode Node newNode.LastX, newNode.LastY, newNode.X, newNode.Y = now.X, now.Y, now.X, now.Y - 1 sq.Base[sq.Rear] = newNode sq.Rear++ } } fmt.Print("无法到达终点\n") } func main() { map1 = [][]int {{1, 0, 1, 1}, {1, 1, 1, 1}, {1, 0, 1, 1}} hasPassedArea = [][]int {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}} m, n = 4, 3 fmt.Println("迷宫为") for i:= 0; i < len(map1); i++ { for j := 0; j < len(map1[i]); j++ { fmt.Print(map1[i][j], " ") } fmt.Println() } var newNode Node newNode.X, newNode.Y, newNode.LastX, newNode.LastY = 0, 0, -1, -1 sq.Front, sq.Rear = 0, 0 sq.Base[sq.Rear] = newNode sq.Rear++ FindPath(0, 0) }