1. 程式人生 > 實用技巧 >寬度優先搜尋演算法

寬度優先搜尋演算法

寬度優先搜尋演算法

演算法簡介

寬度優先搜尋又稱廣度優先搜尋或橫向優先搜尋。該演算法是一種圖形搜尋演算法,該演算法是從起點開始搜尋然後一層一層的向下搜尋,如果找到目標或者搜尋完了全部的節點則演算法結束。

實戰練習

迷宮尋路問題的求解可以用到該演算法來解決。解決該問題時需要處理好兩個核心的部分。第一個部分為尋找下一層(新的可行位置),第二個部分為記入新的可行位置。由於尋找過程是一層一層的向下尋找,即探索完一個節點後需要記入新的可行位置和到達這一位置的上一個節點,並且把該位置出列然後開始下一個結點的尋找,在這裡就用佇列儲存資料(先進先出)。由於每一次尋找到的可行位置都記錄了到達這一點的上一個位置,此時就可以利用演算法最後搜尋到的終點一層一層的倒序輸出(因為每一個尋找到的位置都記錄了上一個位置)輸出得到的結果就是可行路徑。為了防止尋找到的位置是已經尋找過的位置,就把已經走過的位置標記一下,在這裡我把它標記為-1。

原始碼圖片如下:
寬度優先搜尋演算法
原始碼如下:
#include
#include<stdlib.h>
using namespace std;
typedef struct {
int x;
int y;
int last;//記錄上一個標號
}decation;
typedef struct {
decation* point;
int length;
int list_size;
}LIST;
int lybyrince[10][10] = { 1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,1,
1,0,1,1,1,1,1,1,0,1,
1,1,0,1,1,1,1,1,0,1,
1,0,1,0,1,1,1,1,0,1,
1,1,1,1,0,1,1,1,0,1,
1,1,1,0,1,1,1,1,1,1,
1,1,1,1,0,1,1,1,0,1,
1,1,1,1,1,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1 };
int xx[9] = { 0,1,1,0,-1,-1,-1,0,1 };//不同方向下的x的偏移值
int yy[9] = { 0,0,-1,-1,-1,0,1,1,1 };//不同方向下的y的偏移值
int search_direct(int a, LIST& b, int c, int d);
void show(LIST a);
int main()
{
int biaozhi;
int n = 1;
int last_x = 8; int last_y = 8;
decation* p;
LIST list;
list.point = (decation*)malloc(100 * sizeof(decation));
list.length = 2; list.list_size = 100;
p = list.point;
p[0].last = 0;
p[1].x = 1; p[1].y = 1; p[1].last = 0;//記入開始位置
lybyrince[1][1] = -1;//把走過的位置記為-1,防止尋找到的位置是走過的
while (1)
{
biaozhi = search_direct(n, list, last_x, last_y);
if (biaozhi) break;//知道尋找到終點結束迴圈
n = n + 1;//一層一層向外尋找可以通過的路徑
}
show(list);
}
int search_direct(int a, LIST& b, int c, int d)
{
decation* pp = b.point;
int i = b.length-1;
for (int n = 1; n <= 8; n++)//一共八個方向
{
if (lybyrince[pp[a].x + xx[n]][pp[a].y + yy[n]] == 0)//尋找沒有走過的並且沒有障礙的位置
{
pp[i + 1].x = pp[a].x + xx[n]; pp[i + 1].y = pp[a].y + yy[n];//計入新找到的可行位置的座標
pp[i + 1].last = a;//記入這一步的位置是由哪一步到來的
i = i + 1;
lybyrince[pp[i].x][pp[i].y] = -1;//此時新到達的位置已經走過了,把他標記為-1;
b.length = b.length + 1;//線性表長度加一
if (pp[i].x == c && pp[i].y == d)
break;//如果找到的位置是終點則結束迴圈
}
}
if (pp[i].x == c && pp[i].y == d) return 1;//如果找到的位置是終點返回一來退出主函式裡的迴圈
else return 0;
}
void show(LIST a)//輸出經過的路徑
{
int n;
n = a.length - 1;
while (n != 0)
{
cout << a.point[n].x << " " << a.point[n].y << endl;
n = a.point[n].last;
}
}