C语言 迷宫问题求解(顺序栈应用示例)
生活随笔
收集整理的這篇文章主要介紹了
C语言 迷宫问题求解(顺序栈应用示例)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[cpp]?view plaincopy //順序棧的應用:迷宮?? //作者:nuaazdh?? //時間:2011年12月7日?? #include?<stdio.h>?? #include?<stdlib.h>?? ?? #define?OK??????1?? #define?ERROR???0?? #define?TRUE????1?? #define?FALSE???0?? #define?STACK_INIT_SIZE?100?? #define?STACKINCREMENT?10?? ?? #define?COLUMN?10???//迷宮行數?? #define?ROW?10??????//迷宮列數?? ?? typedef?int?Status;?//函數返回狀態?? ?? typedef?struct{//迷宮類型?? ????char?**maze;//迷宮數據?? ????int?**footprint;//足跡數據?? ????int?row;//行數?? ????int?column;//列數?? }MazeType;?? ?? typedef?struct{//迷宮位置坐標?? ????int?x;?? ????int?y;?? }PosType;?? ?? typedef?struct{?? ????int?ord;//通道塊在路勁上的"序號"?? ????PosType?seat;//通道塊在迷宮中的"坐標位置"?? ????int?di;//從此通信塊走向下一通道塊的"方向"?? }SElemType;??//棧元素類型?? ?? typedef?struct{//順序棧結構定義?? ????SElemType?*base;?? ????SElemType?*top;?? ????int?stacksize;?? }SqStack;?? ?? Status?InitStack(SqStack?*S);?? ????//構造一個空棧S?? Status?InitMaze(MazeType?*M);?? ????//初始化迷宮數據?? Status?DestroyStack(SqStack?*S);?? ????//銷毀棧S,S不再存在?? Status?ClearStack(SqStack?*S);?? ????//把棧S置為空棧?? Status?StackEmpty(SqStack?S);?? ????//若棧S為空棧,則返回TRUE,否則返回FALSE?? int?StackLength(SqStack?S);?? ????//返回S元素的個數,即棧的長度?? Status?GetTop(SqStack?S,SElemType?*e);?? ????//若棧不為空,則用e返回S的棧頂元素,并返回OK;否則返回FALSE?? Status?Push(SqStack?*S,SElemType?e);?? ????//插入元素e為新的棧頂元素?? Status?Pop(SqStack?*S,SElemType?*e);?? ????//若棧S不為空,則刪除S的棧頂元素,用e返回其值,并返回OK,否則返回ERROR?? Status?StackTraverse(const?SqStack?*S);?? ????//從棧底到棧頂依次對每個元素進行訪問?? Status?PrintMaze(MazeType?*M);?? ????//輸出迷宮?? Status?MazePath(SqStack?*S,MazeType?maze,PosType?start,PosType?end);?? ????//若迷宮maze中存在從入口start到出口end的通道,則求得一條存放在棧中(從棧底?? ????//到棧頂),并返回TRUE;否則返回FALSE?? Status?FootPrint(MazeType?*M,PosType?pos);?? ????//將迷宮的當前位置pos設置為"走過",即footprint該位置為1?? Status?Pass(MazeType?*M,PosType?pos);?? ????//判斷當前位置是否走過?? SElemType?NewSElem(int?step,PosType?pos,int?d);?? ????//創建新結點,用step,pos,d初始化該結點?? PosType?NextPos(PosType?pos,int?d);?? ????//將位置pos的方向設為d?? Status?MarkPrint(MazeType?*M,PosType?pos);?? ????//將迷宮M的pos位置,設為已走,成功返回OK;否則返回ERROR?? Status?PrintFoot(MazeType?*M,SqStack?*S);?? ????//輸出迷宮的路徑?? int?main()?? {?? ????MazeType?maze;//迷宮結構?? ????SqStack?stack;//順序棧,存儲迷宮路徑?? ????PosType?start,end;//迷宮的起點和終點;?? ????start.x=0;start.y=1;//迷宮的起點?? ????end.x=8;end.y=9;//迷宮的終點?? ????InitMaze(&maze);//迷宮初始化?? ????printf("迷宮形狀:\n");?? ????PrintMaze(&maze);//打印迷宮形狀?? ????if(TRUE==MazePath(&stack,maze,start,end))?? ????????printf("迷宮可解.\n");?? ????else?? ????????printf("迷宮不可解.\n");?? ????return?0;?? }?? ?? Status?InitStack(SqStack?*S){?? ????//構造一個空棧S?? ????S->base=(SElemType?*)malloc(STACK_INIT_SIZE*sizeof(SElemType));?? ????if(!S->base)//分配失敗?? ????{?? ????????printf("分配內存失敗.\n");?? ????????exit(0);?? ????}?? ????S->top=S->base;?? ????S->stacksize=STACK_INIT_SIZE;?? ????return?OK;?? }?? ?? Status?InitMaze(MazeType?*M){?? ????//初始化迷宮數據?? ????int?i,j;?? ????char?mz[ROW][COLUMN]={?? ????'#','?','#','#','#','#','#','#','#','#',?? ????'#','?','?','#','?','?','?','#','?','#',?? ????'#','?','?','#','?','?','?','#','?','#',?? ????'#','?','?','?','?','#','#','?','?','#',?? ????'#','?','#','#','#','?','?','?','?','#',?? ????'#','?','?','?','#','?','#','?','#','#',?? ????'#','?','#','?','?','?','#','?','?','#',?? ????'#','?','#','#','#','?','#','#','?','#',?? ????'#','#','?','?','?','?','?','?','?','?',?? ????'#','#','#','#','#','#','#','#','#','#'?? ????};?? ?? ????M->maze=(char?**)malloc(sizeof(char?*)*ROW);?? ????M->footprint=(int?**)malloc(sizeof(int?*)*ROW);?? ????if(!M->maze||!M->footprint){?? ????????printf("申請空間失敗,迷宮無法初始化.\n");?? ????????return?ERROR;?? ????????exit(0);?? ????}?? ????for(i=0;i<ROW;i++){?? ????????M->maze[i]=(char?*)malloc(sizeof(char)*COLUMN);?? ????????M->footprint[i]=(int?*)malloc(sizeof(int)*COLUMN);?? ????????if(!M->maze[i]||!M->footprint[i]){?? ????????????printf("申請空間失敗,迷宮初始化失敗.\n");?? ????????????return?ERROR;?? ????????????exit(0);?? ????????}?? ????}?? ????for(i=0;i<ROW;i++){?? ????????for(j=0;j<COLUMN;j++){?? ????????????M->maze[i][j]=mz[i][j];?? ????????????M->footprint[i][j]=0;?? ????????}?? ????}?? ????M->row=ROW;//行?? ????M->column=COLUMN;//列?? ????return?OK;?? }?? ?? Status?DestroyStack(SqStack?*S){?? ????//銷毀棧S,S不再存在?? ????if(!S)//S為空?? ????{?? ????????printf("指針為空,釋放失敗.\n");?? ????????exit(0);?? ????}?? ????free(S);?? ????return?OK;?? }?? ?? Status?ClearStack(SqStack?*S){?? ????//把棧S置為空棧?? ????if(!S)//S不存在?? ????????return?FALSE;?? ????S->top=S->base;//直接將棧頂指針指向棧底?? ????return?OK;?? }?? ?? Status?StackEmpty(SqStack?S){?? ????//若棧S為空棧,則返回TRUE,否則返回FALSE?? ????if(S.top==S.base)?? ????????return?TRUE;?? ????else?? ????????return?FALSE;?? }?? ?? int?StackLength(SqStack?S){?? ????//返回S元素的個數,即棧的長度?? ????return?S.stacksize;?? }?? ?? Status?GetTop(SqStack?S,SElemType?*e){?? ????//若棧不為空,則用e返回S的棧頂元素,并返回OK;否則返回FALSE?? ????if(S.top==S.base){?? ????????printf("棧為空.\n");?? ????????return?FALSE;?? ????}else{?? ????????*e=*(S.top-1);?? ????????printf("棧頂元素:%c\n",*e);?? ????????return?OK;?? ????}?? }?? ?? Status?Push(SqStack?*S,SElemType?e){?? ????//插入元素e為新的棧頂元素?? ????if(S->top-S->base>=S->stacksize){//棧已滿,追加存儲空間?? ????????S->base=(SElemType?*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(SElemType));?? ????????if(!S->base)?? ????????{?? ????????????printf("重新申請空間失敗.\n");?? ????????????exit(0);?? ????????}?? ????????S->top=S->base+S->stacksize;//更改棧頂指針?? ????????S->stacksize+=STACKINCREMENT;?? ????}?? ????*S->top++=e;?? ????return?OK;?? }?? ?? Status?Pop(SqStack?*S,SElemType?*e){?? ????//若棧S不為空,則刪除S的棧頂元素,用e返回其值,并返回OK,否則返回ERROR?? ????if(S->top==S->base){//棧為空?? ????????printf("棧為空.\n");?? ????????return?ERROR;?? ????}?? ????*e=*(--S->top);?? ????return?OK;?? }?? ?? Status?StackTraverse(const?SqStack?*S){?? ????//從棧底到棧頂依次對每個元素進行訪問?? ????SElemType?*p=S->base;?? ????if(S->base==S->top)?? ????{?? ????????printf("棧為空.\n");?? ????????return?FALSE;?? ????}?? ????printf("棧中元素:");?? ????while(p!=S->top)?? ????{?? ????????printf("x=%d,y=%d\n",p->seat.x,p->seat.y);?? ????????*p++;?? ????}?? ????printf("\n");?? ????return?OK;?? }?? ?? Status?PrintMaze(MazeType?*M){?? ????//輸出迷宮?? ????int?i,j;?? ????for(i=0;i<M->row;i++){?? ????????for(j=0;j<M->column;j++){?? ????????????printf("%c",M->maze[i][j]);?? ????????}?? ????????printf("\n");?? ????}?? ????printf("\n");?? ????return?OK;?? }?? ?? Status?PrintFoot(MazeType?*M,SqStack?*S){?? ????//輸出迷宮的路徑?? ????int?i,j;?? ????SElemType?*p;?? ????for(i=0;i<M->row;i++){?? ????????for(j=0;j<M->column;j++){?? ????????????M->footprint[i][j]=0;?? ????????}?? ????}?? ????p=S->base;?? ????if(S->base==S->top)?? ????{?? ????????printf("棧為空.\n");?? ????????return?FALSE;?? ????}?? ????while(p!=S->top)?? ????{?? ????????M->footprint[p->seat.x][p->seat.y]=1;?? ????????*p++;?? ????}?? ????for(i=0;i<M->row;i++){?? ????????for(j=0;j<M->column;j++){?? ????????????printf("%d",M->footprint[i][j]);?? ????????}?? ????????printf("\n");?? ????}?? ?? ????return?OK;?? }?? ?? Status?MazePath(SqStack?*S,MazeType?maze,PosType?start,PosType?end){?? ????//若迷宮maze中存在從入口start到出口end的通道,則求得一條存放在棧中(從棧底?? ????//到棧頂),并返回TRUE;否則返回FALSE?? ????int?curstep=1;//當前步數?? ????SElemType?e;?? ????PosType?curpos=start;//當前位置?? ????InitStack(S);//初始化棧?? ????do{?? ????????if(TRUE==Pass(&maze,curpos)){?? ????????????FootPrint(&maze,curpos);?? ????????????e=NewSElem(curstep,curpos,1);?? ????????????Push(S,e);?? ????????????if((curpos.x==end.x)&&(curpos.y==end.y)){//到達終點(出口)?? ????????????????printf("迷宮路徑:\n");?? ????????????????//StackTraverse(S);?? ????????????????PrintFoot(&maze,S);?? ????????????????return?TRUE;?? ????????????}?? ????????????curpos=NextPos(curpos,1);?? ????????????curstep++;?? ????????}//if?? ????????else{//當前位置不能通過?? ????????????if(!StackEmpty(*S)){?? ????????????????Pop(S,&e);?? ????????????????while(e.di==4&&!StackEmpty(*S)){?? ????????????????????MarkPrint(&maze,e.seat);?? ????????????????????Pop(S,&e);?? ????????????????}//while?? ????????????????if(e.di<4){?? ????????????????????e.di++;?? ????????????????????Push(S,e);?? ????????????????????curpos=NextPos(e.seat,e.di);?? ????????????????}//if?? ????????????}//if?? ????????}//else?? ????//PrintFoot(&maze,S);?? ????}while(!StackEmpty(*S));?? ????return?FALSE;?? }?? ?? Status?FootPrint(MazeType?*M,PosType?pos){?? ????//將迷宮的當前位置pos設置為"走過",即footprint該位置為1?? ????if((pos.x>M->row)||(pos.y>M->column))?? ????????return?FALSE;?? ????M->footprint[pos.x][pos.y]=1;?? ????????return?TRUE;?? }?? ?? Status?Pass(MazeType?*M,PosType?pos){?? ????//判斷當前位置是否可通,即為走過的通道塊?? ????if((M->row<pos.x)||(M->column<pos.y)){?? ????????printf("位置越位.\n");?? ????????exit(0);?? ????}?? ????if((0==M->footprint[pos.x][pos.y])&&(M->maze[pos.x][pos.y]=='?'))?? ????????return?TRUE;?? ????else?? ????????return?FALSE;?? }?? ?? SElemType?NewSElem(int?step,PosType?pos,int?d){?? ????//創建新結點,用step,pos,d初始化該結點?? ????SElemType?e;?? ????e.ord=step;?? ????e.seat=pos;?? ????e.di=d;?? ????return?e;?? }?? ?? PosType?NextPos(PosType?pos,int?d){?? ????//獲取pos位置d方向的位置?? ????switch(d){?? ????case?1://東?? ????????pos.x++;?? ????????break;?? ????case?2://南?? ????????pos.y++;?? ????????break;?? ????case?3://西?? ????????pos.x--;?? ????????break;?? ????case?4://北?? ????????pos.y--;?? ????????break;?? ????default:?? ????????printf("位置編號出錯.\n");?? ????}?? ????return?pos;?? }?? ?? Status?MarkPrint(MazeType?*M,PosType?pos){?? ????//將迷宮M的pos位置,設為已走,成功返回OK;否則返回ERROR?? ????if(pos.x>M->row||pos.y>M->column){?? ????????printf("所要標記位置越位.\n");?? ????????return?ERROR;?? ????}?? ????M->footprint[pos.x][pos.y]=1;?? ????return?OK;?? }??
運行結果演示:
總結
以上是生活随笔為你收集整理的C语言 迷宫问题求解(顺序栈应用示例)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅析μC/OS-II OSTimeDly
- 下一篇: 浅谈C/C++中的typedef和#de