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)

}

  

posted @ 2020-05-01 18:05  KamishiroShinchi  阅读(335)  评论(0编辑  收藏  举报