萬能的搜索的學(xué)習(xí)——廣度優(yōu)先搜索

廣度優(yōu)先搜索是最簡便的圖的搜索算法之一,屬于一種盲目搜尋法,目的是系統(tǒng)地展開并檢查圖中的所有節(jié)點,以找尋結(jié)果。換句話說,它并不考慮結(jié)果的可能位置,徹底地搜索整張圖,直到找到結(jié)果為止。

深度優(yōu)先是從一個方向一直嘗試下去,直到走不通的時候在回到原來地方繼續(xù)尋找。而廣度優(yōu)先是通過“一層一層”擴展的方法去尋找目標。擴展時每發(fā)現(xiàn)一個點就將這個點加入到隊列中,直到找到目標為止。

例如下面這道題,從起點到達終點需要幾步?

題目.png

最開始從入口(1,1)處,一步之內(nèi)可以到達的點有(1,2)和(2,1),但是終點并不在這兩個點上,那只能通過(1,2)和(2,1)這兩點繼續(xù)往下走,那么兩步之內(nèi)能到達哪些點呢?只有(2,2)和(3,1),為了防止一個點多次被走到,這里需要一個數(shù)組來記錄一個點是否已經(jīng)走過。

此時兩步到達的點事(2,2)和(3,1),可惜終點并不是這兩點,所以還要繼續(xù)往下走,三步能到的點是(2,3)、(3,2)和(4,1),依舊不是終點,所以需要重復(fù)剛才的方法,直到找終點為止。
完整代碼如下:

#include <stdio.h>

struct note {
    int x;  //橫坐標
    int y;  //縱坐標
    int s;  //步數(shù)
};

int main(int argc, const char * argv[]) {
    
    struct note que[17];    //應(yīng)為地圖大小不超過 4X4,因此隊列擴展不會超過16個
    
    // 記錄走過的點,和標記
    int a[5][5] = {0},mark[5][5]= {0};
    
    // 定義一個用于表示走的方向的數(shù)組
    int next[4][2] = {{0,1}, // 向右走
                      {1,0}, // 下
                      {0,-1},// 左
                      {-1,0} // 上
                        };
    
    int head,tail;
    int k,tx,ty,flag;
    
    //隊列初始化
    head = 1;
    tail = 1;
    //往隊列插入迷宮入口坐標
    que[tail].x = 1;
    que[tail].y = 1;
    que[tail].s = 0;
    tail++;
    mark[1][1] = 1; //起點已經(jīng)走過
    
    // 用來標記是否到達目標點,0表示暫時還沒有到達,1表示到達
    flag = 0;
    // 當隊列不為空的時候循環(huán)
    while (head < tail) {
        // 枚舉4個方向
        for (k = 0; k <= 3; k++) {
            
            // 計算下一個點的坐標
            tx = que[tail].x + next[k][0];
            ty = que[tail].y + next[k][1];
            
            // 判斷是否越界
            if (tx <1 || tx >5 || ty <1 || ty >4) continue;
            // 判斷是否是障礙物或者已經(jīng)在路徑中
            if (a[tx][ty] == 0 && mark[tx][ty] == 0) {
                
                // 把這個點標記為已經(jīng)走過,每個點只入隊一次
                mark[tx][ty] = 1;
                // 插入新的點到隊列中
                que[tail].x = tx;
                que[tail].y = ty;
                que[tail].s = que[head].s +1;   // 步數(shù)加1
                tail++;
                
            }
            
            // 如果找到目標點,停止擴展,任務(wù)結(jié)束,退出循環(huán)
            if (tx == 4 && ty == 3) {
                flag = 1;
                break;
            }
        }
        if (flag == 1) {
            break;
        }
        // 當一個點擴展結(jié)束后,head++才能對后面的點再進行擴展
        head++;
    }
    // tail是指向隊列隊尾的下一個位置,所以需要-1
    printf("%d",que[tail -1].s);
    
    getchar();getchar();
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容