任務(wù)描述:
根據(jù)如下的人大校園地圖碧信,給出起點(diǎn)、終點(diǎn)韩肝,尋找并顯示一條通路,或告知通路不存在九榔。
任務(wù)提示:
使用Stack數(shù)據(jù)結(jié)構(gòu)
輸入?yún)?shù)
//出題者給的人大校園地圖哀峻,供參考
//怒問: 明德樓在哪里?
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, 1,0,1,0,0,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,1,1,0,0,0,0,1,1,1,0,0,0,0,1,0,0,0,1,1,0,1,1,1,0,0,1, 1,0,1,1,0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,1,1,0,1,1,1,1,0,1, 1,0,1,1,0,0,0,0,1,1,1,0,0,1,1,0,0,0,0,1,1,0,1,1,1,1,0,1, 1,0,1,1,0,1,1,1,1,1,1,0,0,0,1,0,0,0,0,1,1,0,1,1,1,0,0,1, 1,0,1,1,0,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,1,1,0,1,1,0,0,0,1, 1,0,0,0,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
C語(yǔ)言實(shí)現(xiàn)代碼
工作環(huán)境: Xcode
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
#define W 28 //width
#define H 14 //height
#define INITSIZE (100)
#define INCREMENT (20)
/*Maze program V1.0 送檢版*/
typedef struct{
int x;
int y;
/*dir 0:east; 1:south: 2:west: 3:north*/
int dir;
}ElemType;
typedef struct{
ElemType *base;
int top;
int stacksize;
}SqStack ;
void init_stack(SqStack *S) {
S->base = (ElemType *)malloc(INITSIZE*sizeof(ElemType));
if (!S) {printf("Out of space.\n"); exit(ERROR);}
S->top = 0;
S->stacksize = INITSIZE;
printf("Stack初始化完成. \n");
}
void push(SqStack *S, ElemType e) {
if (S->top >= S->stacksize-1) {
printf("Stack full.\n");
S->base = (ElemType *)realloc(S->base, (INITSIZE+INCREMENT)*sizeof(ElemType));
}
S->base[S->top] = e;
S->top++;
}
void pop(SqStack *S, ElemType *e) {
if (S->top == 0) {
printf("Stack empty.\n");
}
*e = S->base[S->top-1];
S->top--;
}
void print_map(int map[H][W]) {
int i, j;
printf("標(biāo)記: 1代表墻壁,0代表通道,2代表走過的路徑.\n");
printf("Map: \n");
for (i=0; i<H; i++) { //i表示行
for (j=0; j<W; j++) { //j表示列
printf("%d ",map[i][j]);
}
printf("\n");
}
}
int find_path(SqStack *S, int map[H][W], ElemType start, ElemType end) {
/*變量初始化*/
//1,設(shè)置起點(diǎn)為當(dāng)前點(diǎn)
ElemType cur = start;
//2,用count記錄走過的步數(shù)
int count = 0;
/*開始運(yùn)行*/
do {
printf("loop\n");
count++;
/*是否終點(diǎn)*/
if (cur.x==end.x && cur.y==end.y) {
map[cur.y][cur.x] = 2;
printf("到達(dá)終點(diǎn), 使用了%d步.\n",count);
return 0;
}
switch (0) { //switch先從東方向開始探測(cè)
/*東方向*/
case 0:
//先寫好當(dāng)前點(diǎn)的方向;
cur.dir = 0;
/*可以通行*/
//需要滿足該點(diǎn)本身在圖中是0, 而且沒有被標(biāo)記過;
if (map[cur.y][cur.x+1]==0){
/*跳入下一個(gè)位置*/
//1, 當(dāng)前點(diǎn)入棧
push(S, cur);
//1, 修改地圖上的當(dāng)前點(diǎn)當(dāng)做踩過的點(diǎn)為2
map[cur.y][cur.x] = 2;
printf("(%d,%d)\n",cur.x,cur.y);
//2, 修改當(dāng)前點(diǎn)
cur.x++;
break; //這個(gè)break是跳出switch選擇;
}
/*南方向*/
case 1:
//先寫好當(dāng)前點(diǎn)的方向;
cur.dir = 1;
/*可以通行*/
//需要滿足該點(diǎn)本身在圖中是0, 而且沒有被標(biāo)記過;
if (map[cur.y+1][cur.x]==0){
/*跳入下一個(gè)位置*/
//1, 當(dāng)前點(diǎn)入棧
push(S, cur);
//1, 修改地圖上的當(dāng)前點(diǎn)當(dāng)做踩過的點(diǎn)為2
map[cur.y][cur.x] = 2;
printf("(%d,%d)\n",cur.x,cur.y);
//2, 修改當(dāng)前點(diǎn)
cur.y++;
break; //這個(gè)break是跳出switch選擇;
}
/*西方向*/
case 2:
//先寫好當(dāng)前點(diǎn)的方向;
cur.dir = 2;
/*可以通行*/
//需要滿足該點(diǎn)本身在圖中是0, 而且沒有被標(biāo)記過;
if (map[cur.y][cur.x-1]==0){
/*跳入下一個(gè)位置*/
//1, 當(dāng)前點(diǎn)入棧
push(S, cur);
//1, 修改地圖上的當(dāng)前點(diǎn)當(dāng)做踩過的點(diǎn)為2
map[cur.y][cur.x] = 2;
printf("(%d,%d)\n",cur.x,cur.y);
//2, 修改當(dāng)前點(diǎn)
cur.x--;
break; //這個(gè)break是跳出switch選擇;
}
/*北方向*/
case 3:
//先寫好當(dāng)前點(diǎn)的方向;
cur.dir = 3;
/*可以通行*/
//需要滿足該點(diǎn)本身在圖中是0, 而且沒有被標(biāo)記過;
if (map[cur.y-1][cur.x]==0){
/*跳入下一個(gè)位置*/
//1, 當(dāng)前點(diǎn)入棧
push(S, cur);
//1, 修改地圖上的當(dāng)前點(diǎn)當(dāng)做踩過的點(diǎn)為2
map[cur.y][cur.x] = 2;
printf("(%d,%d)\n",cur.x,cur.y);
//2, 修改當(dāng)前點(diǎn)
cur.y--;
break; //這個(gè)break是跳出switch選擇;
}
/*四個(gè)方向都探測(cè)不通*/
default:
pop(S, &cur);
printf("(%d,%d)\n",cur.x,cur.y);
break;
}
} while (cur.x!=start.x || cur.y!=start.y); //當(dāng)一路退回到了起點(diǎn),就跳出循環(huán),表示失敗了;
printf("找不到終點(diǎn).\n");
return 0;
}
int main()
{
int map[14][28]= //人大校園地圖涡相,供參考, W=28, H=14
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,
1,0,1,0,0,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,1,1,0,0,0,0,1,1,1,0,0,0,0,1,0,0,0,1,1,0,1,1,1,0,0,1,
1,0,1,1,0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,1,1,0,1,1,1,1,0,1,
1,0,1,1,0,0,0,0,1,1,1,0,0,1,1,0,0,0,0,1,1,0,1,1,1,1,0,1,
1,0,1,1,0,1,1,1,1,1,1,0,0,0,1,0,0,0,0,1,1,0,1,1,1,0,0,1,
1,0,1,1,0,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,1,1,0,1,1,0,0,0,1,
1,0,0,0,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
print_map(map);
/*變量初始化: start & end 初始化*/
SqStack S;
init_stack(&S);
ElemType start, end;
start.x = 1; start.y = 1; start.dir = 0;
end.x = W-1-1; end.y = H-1-1;
find_path(&S,map,start,end);
print_map(map);
return 0;
}
/*開發(fā)日志*/
//原本我想在ElemType中加入pre, next, 但是實(shí)際上是不必要的,用pop就可以得到上一個(gè)點(diǎn)
//也就是說(shuō),stack結(jié)構(gòu)自然而然能找到上一個(gè), 因此只要在每個(gè)元素中寫入下個(gè)元素的方向就可以了;
//基礎(chǔ)操作方法準(zhǔn)備完畢;
//17:45第一次測(cè)試: bug發(fā)現(xiàn)是只循環(huán)4次
//23:00去掉了循環(huán)以后, 發(fā)現(xiàn)只進(jìn)行一次尋找;
//8:28 代碼出現(xiàn)了死循環(huán); 而且當(dāng)某個(gè)點(diǎn)發(fā)現(xiàn)不通了,退回上一點(diǎn)的時(shí)候, cur是否有把坐標(biāo)還原到上一點(diǎn)呢? 另外, 還原到上一點(diǎn)以后, 是怎么保證能做繼續(xù)探索其他方向來(lái)找下一點(diǎn)的, 直到都不行才繼續(xù)往回退?
//8:55 代碼運(yùn)行成功, 最后阻止程序正確執(zhí)行的原來(lái)是我的終點(diǎn)條件的x和y檢查寫錯(cuò)了, 居然寫成cur.x==y而不是cur.x==x!
//8:59 添加了記錄步數(shù)的count變量, 增加了注釋;
//9:06 刪除多余注釋,程序完成,可以提交.