(資料結構)棧_迷宮求解(嚴蔚敏P50) _模仿
阿新 • • 發佈:2019-01-29
一般方法(遍歷搜尋,尋求最優):
#include"ds.h" #define MAX_COLUM 10 //迷宮最大列數 #define MAX_ROW 10 //迷宮最大行數 #define MAX_NUM 100 //儲存空間初始分配量,估計實際量設定 int NUM[MAX_NUM]; //記錄curstep int NUM_CURSTEP=0; //實際curstep個數 /*用陣列表示資料結構書中的迷宮,1表示牆壁,0表示通道*/ int a[MAX_ROW][MAX_COLUM]={ {1,1,1,1,1,1,1,1,1,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,0,0,1,1,0,0,1}, {1,0,1,1,1,0,0,0,0,1}, {1,0,0,0,1,0,0,0,0,1}, {1,0,1,0,0,0,1,0,0,1}, {1,0,1,1,1,0,1,1,0,1}, {1,1,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1} }; /*結構體表示座標位置*/ typedef struct Pos{ int x; int y; }Pos; Pos Begin={1,1},End={8,8}; //設定迷宮的進口和出口 int curstep=1; /*最終輸出結果*/ void print() { int i,j; for(i=0;i<MAX_ROW;i++) { for(j=0;j<MAX_COLUM;j++) printf("%d ",a[i][j]); //空格為了方便檢視陣列 printf("\n"); } } void Save(int curstep) //記錄每次成功搜尋所需的步數 { NUM[NUM_CURSTEP++]=curstep; } int Sort(int NUM[]) //獲得最優步數 { int i ,j ,temp; for(i=0;i<NUM_CURSTEP;i++) //冒泡排列,遞增排序 for(j=i+1;j<NUM_CURSTEP;j++) { if(NUM[i]>NUM[j]) { temp=NUM[i]; NUM[i]=NUM[j]; NUM[j]=temp; } } return NUM[0]; } /*路徑搜尋*/ void Path(Pos position ,int curstep) { int i; Pos next_position; Pos direction[4]={{0,1},{1,0},{0,-1},{-1,0}}; //搜尋方向依次為東南西北 for(i=0;i<4;i++) { next_position.x=position.x+direction[i].x; next_position.y=position.y+direction[i].y; if(a[next_position.x][next_position.y]==0) { a[next_position.x][next_position.y]=++curstep; if(next_position.x!=End.x||next_position.y!=End.y) Path(next_position,curstep); else { print(); printf("\n"); Save(curstep); } a[next_position.x][next_position.y]=0; curstep--; } //if end } //for end } int main() { int Minstep=0; printf("迷宮路徑如下:\n"); a[Begin.x][Begin.y]=1; Path(Begin ,1); Minstep=Sort(NUM); printf("迷宮搜尋可行方案總共 %d 組\n",NUM_CURSTEP); printf("迷宮搜尋最優步數為: %d 步\n",Minstep); return 0; }
利用棧(只尋找一條路徑,且很大可能性不是最優路徑,不推薦,只是為了熟悉棧):
#include"ds.h" #define MAX_ROW 7 //迷宮最大行數 #define MAX_COLUMN 7 //迷宮最大列數 #define STACK_INIT_SIZE 10 #define STACK_INCREMENT 2 typedef struct{ //迷宮座標位置 int x; int y; }Pos; typedef struct{ //棧的元素 int ord; //路徑上的序號 Pos seat; //座標位置 int di; //下一步行走的方向 }SElemType; typedef struct{ //棧 SElemType *base; SElemType *top; int stacksize; }SqStack; /*用陣列表示資料結構書中的迷宮,1表示牆壁,0表示通道*/ int a[MAX_ROW][MAX_COLUMN] = { {2, 2, 2, 2, 2, 2, 2}, {2, 0, 0, 0, 0, 0, 2}, {2, 0, 2, 0, 2, 0, 2}, {2, 0, 0, 2, 0, 2, 2}, {2, 2, 0, 2, 0, 2, 2}, {2, 0, 0, 0, 0, 0, 2}, {2, 2, 2, 2, 2, 2, 2} }; Pos Begin={1,1},End={5,5}; //設定迷宮入口和出口 int curstep=1; //步數 SqStack S; //定義一個全域性順序棧 /*構造一個空棧*/ void InitStack(SqStack &S) { S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType)); if(!S.base) exit(OVERFLOW); S.top=S.base; S.stacksize=STACK_INIT_SIZE; } /*判斷一個棧是否為空棧,是返回1,不是返回0*/ int StackEmpty(SqStack S) { if(S.base==S.top) return 1; else return 0; } /*插入e為新的棧頂元素*/ void Push(SqStack &S ,SElemType e) { if((S.top-S.base)>=S.stacksize) { S.base=(SElemType*)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(SElemType)); if(!S.base) exit(OVERFLOW); S.top=S.base+S.stacksize; S.stacksize+=STACK_INCREMENT; } *S.top++=e; } /*若棧不為空,則用e刪除棧頂元素,並返回OK,否則返回ERROR*/ int Pop(SqStack &S ,SElemType &e) { if(S.top==S.base) return ERROR; e=*--S.top; return OK; } /*輸出走迷宮的路徑*/ void FootPrint() { int i,j; for(i=0;i<MAX_ROW;i++) { for(j=0;j<MAX_COLUMN;j++) printf("%d ",a[i][j]); //空格為了觀看方便 printf("\n"); } } /*求當前位置的下一步*/ void NextStep(Pos &seat ,int di) { Pos direction[4]={{0,1},{1,0},{0,-1},{-1,0}}; //方向依次為東南西北 seat.x+=direction[di].x; seat.y+=direction[di].y; } /*搜尋迷宮路徑,只能搜尋一條路徑,且不一定是最優路徑*/ /*若能求得一條路徑則返回TURE,否則返回FALSE*/ int Path(Pos Begin ,Pos End) { Pos CurPos; SElemType e; InitStack(S); CurPos=Begin; //將最初位置設定為入口 do { if(a[CurPos.x][CurPos.y]==0) //此時的位置為通路 { a[CurPos.x][CurPos.y]=curstep; e.ord=curstep; e.seat=CurPos; e.di=0; Push(S,e); curstep++; if(CurPos.x==End.x&&CurPos.y==End.y) return TRUE; NextStep(CurPos,e.di); } //if(a[CurPos.x][CurPos.y]==0) end else { if(!StackEmpty(S)) { Pop(S,e); curstep--; while(e.di==3&&!StackEmpty(S)) { a[e.seat.x][e.seat.y]=-1; Pop(S,e); curstep--; } //while(e.di==3&&!StackEmpty(S)) end if(e.di<3) { e.di++; Push(S,e); curstep++; CurPos=e.seat; NextStep(CurPos,e.di); } //if(e.di<3) } //if(!StackEmpty(S)) end } //else end } while(!StackEmpty(S)); //do end return FALSE; } int main() { if(Path(Begin ,End)) { printf("路徑如下:\n"); FootPrint(); } else { printf("此迷宮走不通\n"); } return 0; }