棧實現迷宮探索問題
阿新 • • 發佈:2018-12-19
該死的資料結構實驗啊,難寫的要死。。。。555555翻了很多部落格,抄一個還是錯的,現在某些人的部落格真是沒良心,坑孩子啊55555,自己百般測試,終於是寫出來一個,親測有用
基本思路就是從入口開始,判斷當前座標是否可走,可走的話就入棧,然後按照上下左右四個方向依次嘗試,下一個節點能走就繼續嘗試,不能走就返回棧頂元素繼續嘗試下一個方向,然後入棧剛剛出棧的這個座標,當四個方向走完的時候,再次返回這個彈出來的座標就不能入棧了,繼續彈出一個座標,嘗試彈出來的這個座標的下一個方向。。。。依次迴圈,直到棧為空,或者走到終點。棧為空說明沒有出路。
還有個小心得哈,就是寫題之前好好想想要不要用指標,反正混著用很麻煩,這次就是把Position改成指標又改回來,反反覆覆,麻煩死了。
還有就是指標一定要malloc,要不然出錯的,這次就是老是吧該分配記憶體的沒分配,直接拿著個沒初始化的指標瞎比劃,浪費了很多時間,只有是變數的結構體才能直接建立而不用初始化。
#include <iostream> #include <cstdio> using namespace std; #define STACKSIZE 100 //棧大小 #define ENTER_ROW 0 //入口行列 #define ENTER_COL 1 #define OUT_ROW 8 //出口行列 #define OUT_COL 9 #define N 10 //迷宮大小 typedef struct p //座標 { int x, y; }Position; typedef struct d { Position position; int dictionary; //記錄走過了多少方向 }DicPosition; typedef struct s //定義棧 { DicPosition array[STACKSIZE]; int rear; int size; }*Stack; //定義迷宮 int mazing[N][N] = { {2,0,2,2,2,2,2,2,2,2},//0 {2,0,0,2,0,0,0,2,0,2},//1 {2,0,0,2,0,0,0,2,2,2},//2 {2,0,0,0,0,2,2,0,0,2},//3 {2,0,2,2,2,0,2,0,2,2},//4 {2,0,0,0,2,0,0,0,0,2},//5 {2,0,2,0,0,0,2,0,0,2},//6 {2,0,2,2,2,0,2,2,0,2},//7 {2,2,0,0,0,0,0,0,0,0},//8 {2,2,2,2,2,2,2,2,2,2} //9 }; Stack initStack(); //初始化棧 bool isEmpty(Stack stack); //空 bool isFull(Stack stack); //滿 bool push(Stack stack, DicPosition dicPosition); //入棧 int pop(Stack stack, DicPosition &dicPosition); //出棧 bool check(Position position); //檢查這個座標是否可走 Position nextPosition(Position position, int direction); //獲得下一個可走座標 int main() { Stack stack = initStack(); Position position; position.x = ENTER_ROW; position.y = ENTER_COL; DicPosition dicPosition; dicPosition.position.x = position.x; dicPosition.position.y = position.y; dicPosition.dictionary = 0; push(stack, dicPosition); //入口一定能走 bool flag = false; while (!isEmpty(stack)) { if (check(position)) //說明能走,就賦值為10,入棧,繼續下一步 { if (flag) //為維持不空,只對首元素入棧時起作用 { dicPosition.position = position; dicPosition.dictionary = 0; push(stack, dicPosition); } mazing[position.x][position.y] = 10; flag = true; //到達出口 if (position.x == OUT_ROW && position.y == OUT_COL) break; position = nextPosition(position, 1); //繼續探索下一個座標 stack->array[stack->rear-1].dictionary = 1; //棧頂元素走過一個方向,計數為1 } else //不能走,就取出當前棧頂元素,嘗試下一個方向 { if (!isEmpty(stack)) //棧不空 { pop(stack, dicPosition); while (dicPosition.dictionary == 4 && !isEmpty(stack)) //檢查是否四個方向都走過 { mazing[dicPosition.position.x][dicPosition.position.y] = 9; //標記9是已經走過 pop(stack, dicPosition); } if (dicPosition.dictionary < 4) //四個方向沒走完,繼續下一個方向 { position = nextPosition(dicPosition.position, dicPosition.dictionary+1); dicPosition.dictionary++; push(stack, dicPosition); //上面彈出的棧頂元素沒有走完四個方向,重新入棧 } } } } for (int i=0; i<N; i++) { for (int j=0; j<N; j++) { printf("%3d ", mazing[i][j]); } printf("\n"); } free(stack); return 0; } Stack initStack() { Stack stack = (Stack) malloc(sizeof(s)); stack->rear = 0; stack->size = STACKSIZE; return stack; } bool isEmpty(Stack stack) { return stack->rear == 0; } bool isFull(Stack stack) { return stack->rear == STACKSIZE - 1; } bool push(Stack stack, DicPosition dicPosition) { if (isFull(stack)) { printf("棧滿!"); return false; } else { stack->array[stack->rear] = dicPosition; stack->rear++; } } int pop(Stack stack, DicPosition &dicPosition) { if (isEmpty(stack)) { printf("棧空"); return 0; } else { stack->rear--; dicPosition = stack->array[stack->rear]; } } bool check(Position position) { if (mazing[position.x][position.y] != 0) //走不通 return false; if (position.x < 0 || position.x >= N) //行越界 return false; if (position.y < 0 || position.y >= N) //列越界 return false; return true; } Position nextPosition(Position position, int direction) { Position temp = position; temp.x = position.x; temp.y = position.y; switch (direction) { case 1:{ temp.x -= 1; //上 break; } case 2:{ temp.x += 1; //下 break; } case 3:{ temp.y -= 1; //左 break; } case 4:{ temp.y += 1; //右 break; } } return temp; }