用棧 求迷宮問題(最短路徑和全部路徑)
阿新 • • 發佈:2018-12-19
這是資料結構的作業,便找書邊看網上,然後自己慢慢寫出來的,這裡面主要是回溯法。 因為課本上是打印出一條路徑,然後我在想怎樣能將所有的路徑都輸出來,方法:就是當求出一條路徑後,將出口點變成可以走的點(因為之前將其值變成了-1),並且將棧頂元素出棧,還需要得到現在棧頂元素的i,j,di值,將其賦出來。 這裡的思路是這樣的,因為找最後一個點的時候是找倒數第二個點的上下左右四個方位,假設說是路徑通暢的點是倒數第二個點的上面的點,當我們找另一條路徑時,那麼現在我們應該順時針從次棧頂右面的點試探,檢視是不是可行的點。 #include <stdio.h> #define Max 9999 int mg[6][6] = { {1,1,1,1,1,1},{1,0,0,0,1,1}, {1,0,1,0,0,1},{1,0,0,0,1,1}, {1,1,0,0,0,1},{1,1,1,1,1,1} }; typedef struct { int i; int j; int di; }BOX; typedef struct { BOX data[Max]; int top; }SqStack; int InitSqStack(SqStack *s) { s->top = -1; return 0; } int Destroy(SqStack *s) { free(s); return 0; } int Push(SqStack *s, BOX *e) { if (s->top == Max - 1) return 0; s->top++; s->data[s->top] = *e; return 0; } int GetTop(SqStack *s, BOX *e) { if (s->top == -1) return 1; *e = s->data[s->top]; return 0; } int Pop(SqStack *s, BOX *e) { if (s->top == -1) return 1; *e = s->data[s->top]; s->top--; return 0; } int Empty(SqStack *s) { if (s->top == -1) return 1; else return 0; }//1是空,0是非空。 int Man(SqStack *s) { if (s->top == Max - 1) return 1; else return 0; } int zmg(int x, int y, int xe, int ye) { SqStack S; BOX path[Max], e, E; BOX shortpath[Max]; int di = 0, x1 = 0, y1 = 0, i = 0, j = 0; int k = 0, fun = 0; int m = 0, lm = 0, n = 0, op = 0; int minlen = Max; int js = 0, tp = 0; InitSqStack(&S);//初始化棧 e.i = x; e.j = y; e.di = -1; Push(&S, &e); mg[x][y] = -1; while (Empty(&S) != 1)//不等於空 { GetTop(&S, &e); i = e.i; j = e.j; di = e.di; if (i == xe && j == ye) { k = 0; tp = S.top; for (js = 0;js <= tp;js++) { S.top = js; printf("\t(%d,%d)", S.data[S.top].i, S.data[S.top].j); shortpath[n] = path[op]; } printf("\n"); if (tp + 1 < minlen) { for (S.top = 0,n = 0;n <=tp;n++,S.top++) { shortpath[n] = S.data[S.top]; } S.top = tp; minlen = tp + 1; } mg[i][j] = 0; Pop(&S, &e); GetTop(&S, &e); i = e.i; j = e.j; di = e.di; } fun = 0; while (di < 4 && fun != 1) { di++; switch (di) { case 0: x1 = i - 1; y1 = j; break; case 1: x1 = i; y1 = j + 1; break; case 2: x1 = i + 1; y1 = j; break; case 3: x1 = i; y1 = j - 1; break; } if (mg[x1][y1] == 0) fun = 1; } if (fun == 1) { S.data[S.top].di = di; e.i = x1; e.j = y1; e.di = -1; Push(&S, &e); mg[x1][y1] = -1; } else { Pop(&S, &e); mg[e.i][e.j] = 0; } } printf("\n"); printf("最短路徑的長度%d,M:",minlen); for(n=0;n<minlen;n++) { printf("\t(%d,%d)",shortpath[n].i,shortpath[n].j); } Destroy(&S); return 0; } int main() { printf("迷宮所有路徑如下:\n"); zmg(1, 1, 4, 4); return 0; }