迷宮(寬度優(yōu)先搜索實現(xiàn))

<h4>一、基本思路:</h4>

1.通過隊列(數(shù)組,連續(xù)的地址)實現(xiàn)寬度優(yōu)先搜索闹究,以達(dá)到尋找最短路徑的目的髓棋。
2.通過一個二維數(shù)組輸出路線(以坐標(biāo)的形式)。

<h4>二、代碼解釋:</h4>

//寬度優(yōu)先搜索 迷宮
#include <stdio.h>
#define maxQueue 15
#define maxMazeRow 10
#define maxMazeCol 10

這個是一些頭文件和其他信息:
1.maxQueue指的是隊列數(shù)組的最大空間。
2.maxMazeRow和maxMazeCol指的是可輸入迷宮的最大長度和寬度。

typedef struct adddress{
    int row;
    int col;
}Points;

定義一個結(jié)構(gòu)體數(shù)組來記錄坐標(biāo)點搞监,包括隊列的數(shù)組也是以這個為結(jié)構(gòu)的數(shù)組。

Points queue[maxQueue]={};  //define the queue

static int bot=0;  //queue's bottom
static int top=0;  //queue's top

void push(Points p)  //push the queue
{
    queue[top]=p;
    top=(top+1)%maxQueue;
}

Points pop(void)  //pop the queue
{
    Points pi={0,0};
    queue[bot]=pi;
    bot=(bot+1)%maxQueue;
    return queue[bot];
}

int is_empty()  //judge the queue is(not) empty
{
    return top==bot;
}


void print_queue()  //print the queue
{
    int i;
    for(i=0;i<maxQueue;i++)
        printf("(%d %d)  ",queue[i].row,queue[i].col);
    printf("\n");
}

以上代碼是有關(guān)隊列的一些內(nèi)容镰矿,包括創(chuàng)建隊列琐驴,也就是數(shù)組queue,還有top和bot分別指的是隊列的頭和尾,push绝淡、pop宙刘、is_empty分別是入隊、出隊牢酵、判斷隊列是否為空悬包。

int arrow[][2]={{0,1},{1,0},{-1,0},{0,-1}};  //up,down,left,right(directions)

Points visited_last[maxMazeRow][maxMazeCol]={};  //store the line

arrow是待會需要往當(dāng)前位置的四個方向搜索的那四個方向,具體的是向上馍乙、向右布近、向左、向下丝格。

visited_last存儲的是路線撑瞧,舉個例子,比如說當(dāng)前走到(3显蝌,4)预伺,而這位置是從(2,4)走來的琅束,那么在visited_last[3][4]儲存的是一個坐標(biāo)(2,4)算谈,這樣的話待會就可以輸出路線了涩禀。

void print_maze(int maxRow,int maxCol,int *maze)
{
    int i,j;
    for(i=0;i<maxRow;i++){
        for(j=0;j<maxCol;j++)
            printf("%d ",*((maze+i*maxMazeCol)+j));
        printf("\n");
    }
    printf("\n");
}


void print_road(Points p)
{
    if(p.col==0&&p.row==0)
        return ;
    else if(p.col!=0||p.row!=0)
    {
        p = visited_last[p.row][p.col];
        print_road(p);
        printf("(%d, %d)\n", p.row, p.col);
    }
}

這兩個分別是輸出迷宮的圖和輸出路線,因為我們用visited_last是倒過來回去輸出的然眼,也就是說坐標(biāo)是從終點往起點輸出的艾船,所以我們需要用遞歸使他反過來從起點輸出到終點。


int main()
{
    int maze[maxMazeRow][maxMazeCol]={};
    int maxCol,maxRow;
    printf("input the maze's row and col:\n");
    scanf("%d %d",&maxRow,&maxCol);
    printf("input the maze:\n");
    if(maxCol>10||maxRow>10){
        printf("the max row and col are all 10!");
    }else{
        int i,j;
        for(i=0;i<maxRow;i++){
            for(j=0;j<maxCol;j++){
                scanf("%d",&maze[i][j]);
            }
        }
        printf("\n");
        //input the maze
        Points p={0,0};
        push(p);
        maze[0][0]=2;
        int k;
        while(!is_empty()){
            if(p.row==maxRow-1&&p.col==maxCol-1)
                break;
            for(k=0;k<4;k++){
                if((p.row+arrow[k][0]<maxRow&&p.col+arrow[k][1]<maxCol)&&p.row+arrow[k][0]>=0&&
                   p.col+arrow[k][1]>=0&&maze[p.row+arrow[k][0]][p.col+arrow[k][1]]==0){
                    maze[p.row+arrow[k][0]][p.col+arrow[k][1]]=2;
                    visited_last[p.row+arrow[k][0]][p.col+arrow[k][1]]=p;
                    Points visitpoint={p.row+arrow[k][0],p.col+arrow[k][1]};
                    push(visitpoint);
                   //search the maze's point , mark the path.
                }
            }
            p=pop();
        }
        if (p.row == maxRow - 1 && p.col == maxCol - 1)  //print the line
        {
            print_road(p);
            printf("(%d, %d)\n", p.row, p.col);//print the path
        }else
            printf("No path!\n");
    }
    return 0;
}

主函數(shù)功能主要看里面的備注即可高每。

<h4>三屿岂、總結(jié)</h4>

本次作業(yè)與上周類似,只不過使用了寬度優(yōu)先搜索(廣度優(yōu)先搜索)鲸匿,用廣度優(yōu)先搜索的好處就是能夠最先找到最短路徑爷怀,而深度優(yōu)先搜索他是一條路徑搜到底不通才倒過來繼續(xù)搜索下一條路徑,也就是說最先搜索到終點的那條路徑就是出路带欢,至于哪條路是取決于你的搜索方向的先后順序运授。
總的來說,這兩種搜索方式有類比之處乔煞,但也有不同之處吁朦,若用樹狀圖理解的話,相信會很好理解的渡贾。

<h4>附:完整代碼</h4>

//寬度優(yōu)先搜索 迷宮
#include <stdio.h>
#define maxQueue 15
#define maxMazeRow 10
#define maxMazeCol 10
#define bool _Bool
typedef struct adddress{
    int row;
    int col;
}Points;

Points queue[maxQueue]={};  //define the queue

static int bot=0;  //queue's bottom
static int top=0;  //queue's top

void push(Points p)  //push the queue
{
    queue[top]=p;
    top=(top+1)%maxQueue;
    
}

Points pop(void)  //pop the queue
{
    Points pi={0,0};
    queue[bot]=pi;
    bot=(bot+1)%maxQueue;
    return queue[bot];
    
}

int is_empty()  //judge the queue is(not) empty
{
    return top==bot;
}


void print_queue()  //print the queue
{
    int i;
    for(i=0;i<maxQueue;i++)
        printf("(%d %d)  ",queue[i].row,queue[i].col);
    printf("\n");
}


int arrow[][2]={{0,1},{1,0},{-1,0},{0,-1}};  //up,down,left,right(directions)

Points visited_last[maxMazeRow][maxMazeCol]={};  //store the line


void print_maze(int maxRow,int maxCol,int *maze)
{
    int i,j;
    for(i=0;i<maxRow;i++){
        for(j=0;j<maxCol;j++)
            printf("%d ",*((maze+i*maxMazeCol)+j));
        printf("\n");
    }
    printf("\n");
}


void print_road(Points p)
{
    if(p.col==0&&p.row==0)
        return ;
    else if(p.col!=0||p.row!=0)
    {
        p = visited_last[p.row][p.col];
        print_road(p);
        printf("(%d, %d)\n", p.row, p.col);
    }
}


int main()
{
    int maze[maxMazeRow][maxMazeCol]={};
    int maxCol,maxRow;
    printf("input the maze's row (max 10) and col (max 10):\n");
    scanf("%d %d",&maxRow,&maxCol);
    printf("input the maze:\n");
    if(maxCol>10||maxRow>10){
        printf("the max row and col are all 10!");
    }else{
        int i,j;
        for(i=0;i<maxRow;i++){
            for(j=0;j<maxCol;j++){
                scanf("%d",&maze[i][j]);
            }
        }
        printf("\n");
        Points p={0,0};
        push(p);
        maze[0][0]=2;
        int k;
        while(!is_empty()){
            if(p.row==maxRow-1&&p.col==maxCol-1)
                break;
            for(k=0;k<4;k++){
                if((p.row+arrow[k][0]<maxRow&&p.col+arrow[k][1]<maxCol)&&p.row+arrow[k][0]>=0&&
                   p.col+arrow[k][1]>=0&&maze[p.row+arrow[k][0]][p.col+arrow[k][1]]==0){
                    maze[p.row+arrow[k][0]][p.col+arrow[k][1]]=2;
                    visited_last[p.row+arrow[k][0]][p.col+arrow[k][1]]=p;
                    Points visitpoint={p.row+arrow[k][0],p.col+arrow[k][1]};
                    push(visitpoint);
                }
            }
            print_queue();
            p=pop();
            print_maze(maxRow,maxCol,maze);  //print the maze
        }
        if (p.row == maxRow - 1 && p.col == maxCol - 1)  //print the line
        {
            print_road(p);
            printf("(%d, %d)\n", p.row, p.col);
        }else
            printf("No path!\n");
    }
    return 0;
}


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末逗宜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纺讲,老刑警劉巖擂仍,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異刻诊,居然都是意外死亡防楷,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門则涯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來复局,“玉大人,你說我怎么就攤上這事粟判∫诨瑁” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵档礁,是天一觀的道長角钩。 經(jīng)常有香客問我,道長呻澜,這世上最難降的妖魔是什么递礼? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮羹幸,結(jié)果婚禮上脊髓,老公的妹妹穿的比我還像新娘。我一直安慰自己栅受,他們只是感情好将硝,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著屏镊,像睡著了一般依疼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上而芥,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天律罢,我揣著相機與錄音,去河邊找鬼棍丐。 笑死弟翘,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的骄酗。 我是一名探鬼主播稀余,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼趋翻!你這毒婦竟也來了睛琳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎师骗,沒想到半個月后历等,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡辟癌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年寒屯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片黍少。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡寡夹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出厂置,到底是詐尸還是另有隱情菩掏,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布昵济,位于F島的核電站智绸,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏访忿。R本人自食惡果不足惜瞧栗,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望海铆。 院中可真熱鬧迹恐,春花似錦、人聲如沸游添。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唆涝。三九已至,卻和暖如春唇辨,著一層夾襖步出監(jiān)牢的瞬間廊酣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工赏枚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留亡驰,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓饿幅,卻偏偏與公主長得像凡辱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子栗恩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理透乾,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,506評論 25 707
  • 目錄 1.分支限界法簡介1.1 分支限界法的本質(zhì)——通過限界阻塞子樹1.2 分支限界法與回溯法的區(qū)別1.3 下界或...
    王偵閱讀 26,938評論 2 13
  • 吸血鬼日記是我最喜歡的美劇之一乳乌,好像沒有喜歡過什么其他的捧韵。說之一是因為如果萬一在將來的遙遠(yuǎn)的某一天我喜歡了其他的電...
    我愛炎熱的夏季閱讀 244評論 0 1
  • 昨天突然知道了好多事 突然明白了xl當(dāng)時的感覺 "因為知道了一些事,一下子有些受不了汉操,喝得急了再来。" 其實也沒有很大...
    抱抱兔子寫寫文_閱讀 143評論 0 0