golang廣度優先算法-走迷宮

廣度優先遍歷,走迷宮思路:
一、建立二維數組,0表示是路,1表示是牆;建立隊列Q,存儲可遍歷的點,Q的第一個元素爲起始點
二、從隊列中取一個點,開始,按上、左、下、右的順序遍歷周圍的點next,next點在數組的範圍內,且值爲0,則把next存入隊列Q中,並在steps(行走記錄二維數組)中記錄步數,該點周圍的四個點遍歷完後,從Q中取下一個點,重複以上步驟,直到Q中沒有點或者當前點爲終點爲止
三、最後打印steps即爲迷宮路線
代碼:
package main

import (
    "fmt"
    "os"
)

type point struct {
    i, j int
}

//獲取臨近的點
func (p point) add(r point) point {
    return point{p.i + r.i, p.j + r.j}
}

//判斷點是否在二維數組中,並返回點的值
func (p point) at(grid [][]int) (int, bool) {
    if p.i < 0 || p.i >= len(grid) {
        return 0, false
    }
    if p.j < 0 || p.j >= len(grid[p.i]) {
        return 0, false
    }
    return grid[p.i][p.j], true
}

//點的遍歷順序,上、左、下、右
var dirs = [4]point{
    {-1, 0}, {0, -1}, {1, 0}, {0, 1},
}

func walk(maze [][]int, start, end point) [][]int {

    steps := make([][]int, len(maze))

    for i := range steps {
        steps[i] = make([]int, len(maze[i]))
    }

    Q := []point{start}

    for len(Q) > 0 {
        cur := Q[0]
        Q = Q[1:]

        if cur == end {
            break
        }

        for _, dir := range dirs {
            next := cur.add(dir)

            val, ok := next.at(maze)

            //next點在數組中,且不能爲牆 ,next點不能是起點
            if !ok || val != 0 {
                continue
            }

            if next == start {
                continue
            }

            if steps[next.i][next.j] == 0 && next.i <= end.i && next.j <= end.j {
                curSteps, _ := cur.at(steps)
                steps[next.i][next.j] = curSteps + 1
                Q = append(Q, next)
            }

        }
    }
    return steps
}

func readMaze(fileName string) [][]int {
    file, _ := os.Open(fileName)

    defer file.Close()
    var row, col int
    fmt.Fscanf(file, "%d %d", &row, &col)

    maze := make([][]int, row)
    for i := range maze {
        maze[i] = make([]int, col)
        for j := range maze[i] {
            fmt.Fscan(file, &maze[i][j])
        }
    }
    return maze
}

func main() {

    maze := readMaze("arr.in")
    steps := walk(maze, point{0, 0}, point{len(maze) - 1, len(maze[0]) - 1})
    for _, row := range steps {
        for _, val := range row {
            fmt.Printf("%3d ", val)
        }
        fmt.Println()
    }
}

打印結果:數組

 

arr.in文件內容app

6 5
0 1 0 0 0
0 0 0 1 0
0 1 0 1 0
1 1 1 0 0
0 1 0 0 1
0 1 0 0 0
相關文章
相關標籤/搜索