日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

迷宫问题(C语言)

發布時間:2024/1/1 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 迷宫问题(C语言) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

迷宮尋路C語言

  • 一、棧
    • 1.名詞
    • 2.棧的實現
      • 棧元素的結構:
      • 初始化棧
      • 入棧
      • 出棧
  • 二、迷宮問題
    • 1.定義迷宮類型
    • 2.迷宮分析
      • 1.迷宮的初始化
      • 2.迷宮顯示
      • 3.迷宮尋路
    • 3.運行結果
  • 三.全部程序和參考書籍

一、棧

棧又是線性表,但是它是一個受限制的線性表。線性表可以自由得刪除或插入節點,但棧只能在棧頂刪除(出棧)或插入(入棧)。(見下圖)

順序表的插入與刪除:

棧的入棧與出棧:

1.名詞

棧就像是一個堆放積木的盒子,與盒子等大的積木就像是棧元素,先放進去的積木總是最后才能被取出來,它只能依次從盒子頂端開始取。
棧頂
最后入棧的下一個元素,是棧的最上面的元素
棧底
最開始(第一個)入棧的元素,是棧的最下面的元素
棧頂指針
指向棧頂元素
棧底指針
指向棧底元素
空棧和初始棧
棧頂指針指向棧頂指針,表示該棧可能是空棧(初始化的棧是空棧)

2.棧的實現

棧元素的結構:

/* 順序棧元素類型定義 */ typedef int SElemType;// 順序棧元素結構 typedef struct {SElemType* base; // 棧底指針SElemType* top; // 棧頂指針int stacksize; // 當前已分配的存儲空間,以元素為單位 } SqStack;

其中

SElemType* base; // 棧底指針 //棧底指針,主要用于接收動態分配空間的首地址。SElemType* top; // 棧頂指針 //棧頂指針,主要用于入棧和出棧。

初始化棧

"->"是指針式訪問結構體成員

typedef int Status;/* *初始化棧(空棧) *初始化成功返回OK,否則返回ERROR */ Status InitStack(SqStack* S) {if(S == NULL) {return ERROR;}//分配棧空間S->base = (SElemType*) malloc(STACK_INIT_SIZE * sizeof(SElemType));if(S->base == NULL) {exit(1);//非正常結束當前進程}S->top = S->base;S->stacksize = STACK_INIT_SIZE;return OK; }

入棧

/* *入棧(將e壓入棧) *入棧成功返回OK,否則返回ERROR */ Status Push(SqStack* S, SElemType e) {if (S->base == NULL || S == NULL)return ERROR;//若棧滿了,則增加空間if (S->top - S->base >= S->stacksiaze){S->base = (SElemType*)realloc(S->base,(S->stacksiaze + STACKINCREMENT) * sizeof(SElemType));if (S->base == NULL)exit(1);//分配失敗S->top = S->base + S->stacksiaze;S->stacksiaze += STACKINCREMENT;}//將e壓入棧(先入棧,棧頂指針再自增)*(S->top++) = e;return OK; }

出棧

/* *出棧(e存入的是出棧的內容) *出棧成功返回OK,否則返回ERROR */ Status Pop(SqStack* S, SElemType* e) {if (S->base == NULL || S == NULL || S->base == S->top)return ERROR;//棧頂指針先遞減*e = *(--(S->top));//當前棧頂指針所指的地址都默認是不用地址,棧頂的前一個地址(--(S->top))才是有用地址return OK; }

二、迷宮問題

迷宮一般來講都是有外墻、迷宮內墻、通路、死胡同、方向(東南西北)、迷宮的方位(x、y坐標)、迷宮大小等等。

1.定義迷宮類型

typedef int MazeType[M][N]; // 迷宮類型 //迷宮類型 typedef enum {Wall, // 外墻Obstacle, // 迷宮內部的障礙Way, // 通路Impasse, // “死胡同”East, South, West, North // 當前探索方向:東南西北 } MazeNode;//通道信息 typedef struct {int x;int y;int di;//下一個訪問的位置 }SElemType;//迷宮棧 typedef struct {SElemType* base; // 棧底指針SElemType* top; // 棧頂指針int stacksize; // 當前已分配的存儲空間,以元素為單位 } SqStack; typedef int MazeType[M][N]; // 迷宮類型

常見的類型定義是:

typedef int** MazeType; // 迷宮類型

二者類似但第一種是為二位數組分配了大小的二維數組,第二個是暫未分配大小的二位數組大小。(第一個已經為二位數組初始化元素為0,第二種是未初始化的二維數組)

2.迷宮分析

1.迷宮的初始化

  • 在初始化階段將迷宮的外形確定下來,包括迷宮的外輪廓(外墻)、迷宮內的障礙(內墻)確定并打印在終端上,為了保證迷宮的不確定性和迷宮尋路的自主性,迷宮的內墻由系統的隨機數發生器隨機的生成內墻的位置。
  • 迷宮的墻壁都是由枚舉類型來給定的,這樣做的好處是代碼閱讀方便容易理解。
  • 迷宮的坐標是由二維數組的下標表示。

如下所示是一個4*4大小的迷宮二維數組,數組中存儲的就是迷宮的類型(外墻、內墻、通路、死胡同,方向),假設1是墻壁,0是通路:

0111
1011
1000
1111

代碼如下:

void InitMaze(MazeType maze, PosType* start, PosType* end) {int tmp;srand((unsigned)time(NULL)); //初始化隨機數發生器for (int i=0;i < M;i++){for (int j = 0;j < N;j++){ //墻壁生成if (i == 0 || j == 0 || i == M - 1 || j == N - 1)maze[i][j] = Wall;//外墻else{tmp = rand() % X;if (tmp == 0)maze[i][j] = Obstacle;//內墻elsemaze[i][j] = Way;//通路}}}//入口start->x = 1;start->y = 0;//出口end->x = M - 2;end->y = N - 1;//開放入口和出口maze[1][0] = maze[M - 2][N - 1] = Way;//提高尋路成功率maze[1][1] = maze[M - 2][N - 2] = Way;// 顯示迷宮的初始狀態PrintMaze(maze); }

2.迷宮顯示

利用switch函數判斷迷宮類型二位數組maze的類型,根據其類型打印迷宮。
其關鍵點:

  • 在每一行的結束位置輸出回車符。
  • 每次進入打印函數,先清屏再打印。

3.迷宮尋路

  • 首先判斷當前位置是否可以通過,判斷依據是當前坐標位置是不是通路;
  • 若當前位置可以通過,則默認先向東訪問并在該坐標下留在訪問的方向標記(東南西北和死胡同);
  • 打印當前坐標的迷宮類型到終端,并且將當前位置壓入棧中;
  • 若當前位置不能通過,若棧不為空,則彈棧,回到上一個位置,上一個位置可能是尋路到了最后一個方向那么就再彈棧,再向上一個位置尋路,如果還沒有尋路到最后一個方向,那么就會在當前位置尋找其他方向的路,直到尋路失敗或尋路成功;
  • 若棧為空,結束迷宮尋路,標準著尋路失敗。
  • 代碼如下:

    Status MazePath(MazeType maze, PosType start, PosType end) {SqStack S;PosType curPos;SElemType e;InitStack(&S);curPos = start;//設置當前位置是入口位置do {//如果當前位置是可以通過的(該位置是從未曾探索過的通道塊)if (Pass(maze, curPos)){//留下足跡(留下向東訪問的標記)FootPrint(maze, curPos);e = Construct(curPos,East);//構造一個通道塊信息并返回Push(&S, e);//將通道塊壓入棧if (Equals(curPos, end)){printf("\n尋路成功!!\n\n");return TRUE;}curPos = NextPos(curPos, East);//獲取下一個要探索的位置}else{if (!StackEmpty(S)){Pop(&S, &e);//退回上一個位置while (e.di == North && !StackEmpty(S)){MarkPrint(maze, e.seat, Impasse);//留下死胡同印記Pop(&S, &e);//繼續退回}if (e.di < North){++e.di;//改變探索方向,按東南西北方向輪詢MarkPrint(maze, e.seat, e.di);//在迷宮下留下訪問標記,用來觀察迷宮的狀態Push(&S, e);//從新將該位置加入到路徑只能curPos = NextPos(e.seat, e.di);}}}} while (!StackEmpty(S));printf("\n尋路失敗\n\n");return FALSE; }

    3.運行結果

    8:向北方向
    4:向西方向
    6:向東方向
    2:向南方向
    0:死胡同
    *:墻壁

    三.全部程序和參考書籍

    下載程序

    參考書籍:嚴蔚敏,吳偉民 《書籍結構(C語言版)》 清華大學出版社(第52頁算法3.3) 書號:9787302147510

    總結

    以上是生活随笔為你收集整理的迷宫问题(C语言)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。