国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題

這篇具有很好參考價(jià)值的文章主要介紹了《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

中國(guó)礦業(yè)大學(xué)信控學(xué)院

?

補(bǔ)一下我之前在博客園發(fā)布的內(nèi)容

?懶得調(diào)了,想復(fù)制完整代碼直接復(fù)制最下面的,想復(fù)制分布代碼去看我博客園鏈接吧

《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題 - 刷子zz - 博客園

一、?問(wèn)題描述

問(wèn)題中迷宮可用方陣[m,n]表示,0表示能通過(guò),1表示不能通過(guò)。若要從從左上角[1,1]進(jìn)入迷宮,設(shè)計(jì)算法,尋求一條從右下角 [m,n] 出去的路徑。我們用遞增的數(shù)來(lái)代表尋找出口方向與步數(shù),用-2來(lái)代表尋找過(guò)程中找錯(cuò)的路徑。

二、?需求分析

?

需要先創(chuàng)建一個(gè)迷宮,在開(kāi)始后就開(kāi)始搜尋,當(dāng)一個(gè)點(diǎn)周圍有0點(diǎn)(改點(diǎn)并不是以搜尋過(guò)的點(diǎn)),那么到這里繼續(xù)往下搜,如果搜到盡頭那么就要倒回去,在搜尋倒回去的周圍還有為搜尋過(guò)得0點(diǎn),因此需要一個(gè)存儲(chǔ)算法,要滿足后入先出,那么就是棧,利用棧就可以滿足需求。

三、?算法分析

?

1.??? 首先先定義棧,本問(wèn)題中,不需要在中間插入與彈出,插入與彈出操作均在棧頭,因此我們利用順序棧。

并且該棧與實(shí)驗(yàn)課的棧不同,因?yàn)橐獫M足實(shí)際需求,所以我們需要定義步數(shù)以及改點(diǎn)所在的位置以及臨近路徑的位置在我們棧中,具體操作如下。

《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題

 1 //記錄通道塊在迷宮矩陣當(dāng)中的橫、縱坐標(biāo) 
 2 struct Position {
 3     int x;
 4     int y;
 5 };
 6 
 7 //放入棧當(dāng)中的通道塊元素 
 8 struct SElement {
 9     int ord;//記錄步數(shù)
10     Position p;//記錄位置 
11     int di;//記錄下一次測(cè)試這一路徑的臨近路徑的位置 
12 };
13 
14 struct MyStack {
15     SElement* base;
16     SElement* top;
17     int stacksize;
18 };

《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題

2.??? 棧的一些列基礎(chǔ)操作,例如創(chuàng)建棧,判斷棧是否為空,取棧頂元素,獲取棧長(zhǎng),入棧,出棧。上述操作類似學(xué)校實(shí)驗(yàn)中基本操作,這里不在敘述,詳見(jiàn)附錄中全部代碼。

3.??? 接下來(lái)創(chuàng)建迷宮,這里迷宮利用數(shù)組來(lái)生成,x軸為n,y軸為m

?? n為18,m為15。生成方法簡(jiǎn)單,這里不在敘述,詳見(jiàn)附錄中全部代碼。

4.??? 接下來(lái)定義如何走這個(gè)迷宮,考慮我們用0作為通道,1作為墻壁,那么搜尋一個(gè)點(diǎn)的上下左右0就是可以通過(guò),1就是不能通過(guò)。利用以下循環(huán)來(lái)完成目標(biāo):

步驟1:挪到0處的點(diǎn)并且把剛才位置入棧,讓改點(diǎn)改為步數(shù),讓步數(shù)加一,然后繼續(xù)搜索其上下左右(除去剛才通過(guò)的點(diǎn))如果有0,繼續(xù)執(zhí)行步驟1。

步驟2:如果周圍的點(diǎn)無(wú)0(除去剛才已經(jīng)通過(guò)的點(diǎn)),讓改點(diǎn)改為-2,那么就出棧,把路徑調(diào)到剛才的那個(gè)點(diǎn),并且把步數(shù)減一,然后執(zhí)行步驟1,搜尋其上下左右(出去剛才走錯(cuò)的點(diǎn)以及入這個(gè)點(diǎn)之前的點(diǎn))。

直至入棧點(diǎn)是終點(diǎn)那么退出循環(huán)。

代碼如下:

《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題

 1 do
 2     {
 3         if (Pass(curp))
 4         {
 5             FootPrint(curp, curStep);//可走就在迷宮里面留下足跡 
 6 //創(chuàng)建一個(gè)棧元素,存儲(chǔ)可行路徑的相關(guān)值
 7             SElement e;
 8             e.di = 1;// 下一個(gè)路塊為這一個(gè)路塊的右邊的路塊 
 9             e.ord = curStep;
10             e.p.x = curp.x;
11             e.p.y = curp.y;
12             Push(&path, e);//將路徑塊入棧 
13 if (curp.x == m - 2 && curp.y == n - 2) break; //如果被壓入的路徑塊到了迷宮的終點(diǎn)就退出循環(huán)
14             //找到下一個(gè)被試塊
15 curp = NextPosition(curp, 1);//找到前一個(gè)被試塊東面的路徑塊作為被試塊
16             curStep++;//被探索的步數(shù)加一 
17         }
18         else//如果當(dāng)前被試路徑不能夠通過(guò)的話 
19         {
20             if (!IsStackEmpty(&path))
21             {
22                 SElement e;
23                 Pop(&path, &e);
24                 curStep--;
25                 //將這一段所有的周圍路徑都已經(jīng)被測(cè)試過(guò)的路徑從棧中清除 
26                 while (e.di == 4 && !IsStackEmpty(&path)) {
27                     MarkPrint(e.p);
28                     Pop(&path, &e);
29                     curStep--;
30                 }
31                 //如果當(dāng)前棧頂還有未被測(cè)試的路徑就測(cè)試剩余的周圍路徑 
32                 if (e.di<4)
33                 {
34                     curp = NextPosition(e.p, e.di + 1);
35                     e.di++;
36                     curStep++;
37                     Push(&path, e);
38                 }
39             }
40         }
41     } while (!IsStackEmpty(&path));

《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題

5.??? 在定義上述代碼中如何去搜尋,按照從右到下再到左再到上的方法搜尋。代碼如下:

《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題

 1 //按順時(shí)針?lè)较驈挠议_(kāi)始尋找矩陣當(dāng)中某一個(gè)位置的臨近位置 
 2 Position NextPosition(Position now, int direction)
 3 {
 4     Position next;
 5     int x = now.x;
 6     int y = now.y;
 7     switch (direction)
 8     {
 9         //右 
10         case 1: {
11         next.x = x;
12         next.y = y + 1;
13         break;
14         }
15             //下 
16         case 2: {
17         next.x = x + 1;
18         next.y = y;
19         break;
20         }
21             //左
22         case 3: {
23         next.x = x;
24         next.y = y - 1;
25         break;
26         }
27             //上
28         case 4:{
29         next.x = x - 1;
30         next.y = y;
31         break;
32         }
33         default:break;
34     }
35     return next;
36}

《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題

6.??? 定義是否可以通過(guò)函數(shù),是就返回ture不是就返回false。代碼如下:

《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題

 1 //輔助函數(shù)考察當(dāng)前路徑能否通過(guò) 
 2 bool Pass(Position posi)
 3 {
 4     //只有路徑所在位置的數(shù)字為0的是可以走的 
 5     if (Maze[posi.x][posi.y] == 0)
 6     {
 7         return true;
 8     }
 9     return false;
10 }

《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題

7.??? 定義是入棧和出棧時(shí)如何修改迷宮數(shù)組中的值。代碼如下:

《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題

 1 //改變改點(diǎn)為步驟數(shù) 
 2 void FootPrint(Position p, int step)
 3 {
 4     Maze[p.x][p.y] = step;
 5 }
 6 
 7 //路徑不可走的話就留下-2的標(biāo)記 
 8 void MarkPrint(Position p)
 9 {
10     Maze[p.x][p.y] = -2;
11}

《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題

8.??? 定義打印迷宮函數(shù),這個(gè)就是遍歷整個(gè)數(shù)組,過(guò)程簡(jiǎn)單這里不在敘述,見(jiàn)附錄中全部代碼。

四、?結(jié)論

?編輯ing...

五、?參考文獻(xiàn)

[1] 嚴(yán)蔚敏,吳偉民——《數(shù)據(jù)結(jié)構(gòu)》清華大學(xué)出版社2004.2.1

六、?附錄

完整代碼如下:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-498670.html

#include <stdio.h>
#include <malloc.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

//記錄通道塊在迷宮矩陣當(dāng)中的橫、縱坐標(biāo)
struct Position {
    int x;
    int y;
};

//放入棧當(dāng)中的通道塊元素
struct SElement {
    int ord;//記錄步數(shù)
    Position p;//記錄位置
    int di;//記錄下一次測(cè)試這一路徑的臨近路徑的位置
};

struct MyStack {
    SElement* base;
    SElement* top;
    int stacksize;
};

//創(chuàng)建一個(gè)棧如果創(chuàng)建成功則返回1,否則就返回0
int InitStack(MyStack* s)
{
    s->base = (SElement*)malloc(STACK_INIT_SIZE * sizeof(SElement));//為棧分配初始空間
    if (!s->base) return 0;
    s->top = s->base;//設(shè)定為空棧
    s->stacksize = STACK_INIT_SIZE;
    return 1;
}

//判斷棧是否為空,如果是空的就返回0,否則就返回1
int IsStackEmpty(MyStack* s)
{
    if (s->top == s->base) return true;
    return false;
}

//獲取棧頂元素,如果棧為空就返回0 否則就返回1
int GetTop(MyStack* s, SElement* e)
{
    if (IsStackEmpty(s)) return 0;
    e = s->top - 1;
    return 1;
}

//獲取棧的長(zhǎng)度,并且通過(guò)程序返回
int StackLength(MyStack* s)
{
    return s->top - s->base;
}

//插入元素e為新的棧頂元素,插入成功則返回1,否則返回0
int  Push(MyStack* s, SElement e)
{
    if (s->top - s->base >= STACK_INIT_SIZE)
    {
        s->base = (SElement*)realloc(s->base, (s->stacksize + STACKINCREMENT) * sizeof(SElement));
        if (!s->base) return 0;
        s->top = s->base + s->stacksize;
        s->stacksize += STACKINCREMENT;
    }
    *(s->top) = e;
    s->top++;
    return 1;
}

//彈出棧頂元素賦值給e彈出成功返回1,彈出失敗返回0
int Pop(MyStack* s, SElement* e)
{
    if (IsStackEmpty(s)) return 0;
    *e = *(s->top - 1);
    s->top--;
    return 1;
}

//定義墻元素為1 可走路徑為0 已知路徑為curStep 不能夠通過(guò)的路徑為-2
#define m 15
#define n 18
int Maze[m][n] = {  { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
                    { 1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1 },
                    { 1,0,1,1,1,0,1,0,0,1,0,1,1,1,1,1,0,1 },
                    { 1,0,1,1,1,0,1,0,1,1,0,1,0,1,1,0,0,1 },
                    { 1,0,0,0,0,0,1,0,1,1,0,1,0,0,0,0,1,1 },
                    { 1,1,1,1,0,0,1,0,1,1,0,1,1,1,1,0,1,1 },
                    { 1,1,1,0,0,1,1,0,1,1,0,0,0,1,1,1,1,1 },
                    { 1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,0,1 },
                    { 1,1,1,0,0,0,0,0,0,0,1,1,0,1,1,0,1,1 },
                    { 1,0,0,1,1,1,1,1,1,0,1,1,0,1,0,0,1,1 },
                    { 1,1,0,0,0,0,0,0,0,0,1,0,0,1,0,1,1,1 },
                    { 1,0,0,1,0,1,0,1,0,0,1,1,0,0,0,1,1,1 },
                    { 1,1,0,1,0,1,0,1,1,1,0,0,0,1,1,1,1,1 },
                    { 1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1 },
                    { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 } };

//輔助函數(shù)考察當(dāng)前路徑能否通過(guò)
bool Pass(Position posi)
{
    //只有路徑所在位置的數(shù)字為0的是可以走的
    if (Maze[posi.x][posi.y] == 0)
    {
        return true;
    }
    return false;
}

//按順時(shí)針?lè)较驈挠议_(kāi)始尋找矩陣當(dāng)中某一個(gè)位置的臨近位置
Position NextPosition(Position now, int direction)
{
    Position next;
    int x = now.x;
    int y = now.y;
    switch (direction)
    {
        //右
    case 1: {
        next.x = x;
        next.y = y + 1;
        break;
    }
            //下
    case 2: {
        next.x = x + 1;
        next.y = y;
        break;
    }
            //左
    case 3: {
        next.x = x;
        next.y = y - 1;
        break;
    }
            //上
    case 4:
    {
        next.x = x - 1;
        next.y = y;
        break;
    }
    default:break;
    }
    return next;
}

//改變改點(diǎn)為步驟數(shù)
void FootPrint(Position p, int step)
{
    Maze[p.x][p.y] = step;
}

//路徑不可走的話就留下-2的標(biāo)記
void MarkPrint(Position p)
{
    Maze[p.x][p.y] = -2;
}

//打印出迷宮矩陣
void Display_migong()
{
    for (int i = 0; i<m; i++)
    {
        for (int j = 0; j<n; j++)
        {
            if (Maze[i][j]<0)
                printf("%d ", Maze[i][j]);
            else if (Maze[i][j]<10)
                printf("%d  ", Maze[i][j]);
            else
                printf("%d ", Maze[i][j]);
        }
        printf("\n");
    }
}

int main()
{

    //迷宮程序主體
    MyStack  path;//記錄路徑的棧
    InitStack(&path);//初始化路徑數(shù)組
    Position curp;//當(dāng)前被試位置
    Display_migong();
    //初始化當(dāng)前位置為矩陣入口
    curp.x = 1;
    curp.y = 1;
    int curStep = 1;//被探索的步數(shù)
    do
    {
        if (Pass(curp))
        {
            FootPrint(curp, curStep);//可走就在迷宮里面留下足跡
//創(chuàng)建一個(gè)棧元素,存儲(chǔ)可行路徑的相關(guān)值,將這個(gè)元素存儲(chǔ)到棧當(dāng)中
            SElement e;
            e.di = 1;//下一個(gè)路塊為這一個(gè)路塊的右邊的路塊
            e.ord = curStep;
            e.p.x = curp.x;
            e.p.y = curp.y;
            Push(&path, e);//將路徑塊入棧
if (curp.x == m - 2 && curp.y == n - 2) break; //如果被壓入的路徑塊到了迷宮的終點(diǎn)就退出循環(huán)
curp = NextPosition(curp, 1);//找到前一個(gè)被試塊東面的路徑塊作為被試塊
            curStep++;//被探索的步數(shù)加一
        }
        else//如果當(dāng)前被試路徑不能夠通過(guò)的話
        {
            if (!IsStackEmpty(&path))
            {
                SElement e;
                Pop(&path, &e);
                curStep--;
                //將所有的周圍路徑都已經(jīng)被測(cè)試過(guò)的路徑從棧中清除
                while (e.di == 4 && !IsStackEmpty(&path)) {
                    MarkPrint(e.p);
                    Pop(&path, &e);
                    curStep--;
                }
                //如果當(dāng)前棧頂還有未被測(cè)試的路徑就測(cè)試剩余的周圍路徑
                if (e.di<4)
                {
                    curp = NextPosition(e.p, e.di + 1);
                    e.di++;
                    curStep++;
                    Push(&path, e);
                }
            }
        }
    } while (!IsStackEmpty(&path));
    printf("\n");
    //打印出結(jié)果迷宮矩陣
    Display_migong();
    return 0;
}

到了這里,關(guān)于《數(shù)據(jù)結(jié)構(gòu)與算法分析》課程設(shè)計(jì)——迷宮問(wèn)題的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包