資料結構_迷宮求解
阿新 • • 發佈:2019-02-16
定義迷宮
#include "seqstack.h" #define MAX_ROW 6 //最大行數 #define MAX_COL 6 //最大列數 typedef struct Maze{ int map[MAX_ROW][MAX_COL];//定義地圖 }Maze; void MazeInit(Maze* maze){//迷宮求解 int map[MAX_ROW][MAX_COL]={ { 0, 1, 0, 0, 0, 0 }, { 0, 1, 1, 1, 0, 0 }, { 0, 1, 1, 1, 1, 0 }, { 0, 1, 1, 1, 0, 0 }, { 0, 1, 1, 1, 0, 0 }, { 0, 0, 0, 1, 0, 0 }, }; size_t i = 0; for(;i<MAX_ROW;++i){ size_t j = 0; for(;j<MAX_COL;++j){ maze->map[i][j] = map[i][j]; } } } void MazePrint(Maze* maze){//迷宮列印 size_t i = 0; for(;i<MAX_ROW;++i){ size_t j = 0; for(;j<MAX_COL;++j){ printf("%2d ",maze->map[i][j]); } printf("\n"); } printf("\n"); }
引用標頭檔案
#pragma once #include <stdio.h> #include <stdlib.h> #define FOR_MAZE #ifdef FOR_MAZE typedef struct Point{ int row; int col; }Point; typedef Point SeqStackType; #else typedef char SeqStackType; #endif typedef struct SeqStack{ SeqStackType* data; size_t size; size_t capacity; }SeqStack; void SeqStackInit(SeqStack* s);//棧初始化 void SeqStackPush(SeqStack* s,SeqStackType value);//壓棧 void SeqStackReSize(SeqStack* s);//更改大小 void SeqStackPop(SeqStack* s);//出棧 int SeqStackTop(SeqStack* s,SeqStackType* value);//取棧頂元素 void SeqStackDestroy(SeqStack* s);//銷燬
遞迴版本
////////////////////////////////////////////////////////////////////////////////////// // Round1 遞迴版本 ///////////////////////////////////////////////////////////////////////////////////// //是否能落腳,能返回1,不能返回0 int CanStay(Maze* maze,Point pt){ //判斷點是否在地圖上 if(pt.row < 0 || pt.row >= MAX_ROW || pt.col < 0 || pt.col >= MAX_COL){ return 0; } int value = maze->map[pt.row][pt.col]; if(value == 1){ return 1; } return 0; } void Mark(Maze* maze,Point cur){ maze->map[cur.row][cur.col] = 2; return; } int IsExit(Maze* maze,Point cur,Point entry){ (void)maze; //如果當前點到了邊界,即為找到了出口,但是不能是入口點 if(cur.row == entry.row && cur.col == entry.col){ return 0; } if(cur.row == 0 || cur.row == MAX_ROW-1 || cur.col == 0 || cur.col == MAX_COL-1){ return 1; } return 0; } void _GetPath(Maze* maze,Point cur,Point entry){ printf("row:%d col:%d\n",cur.row,cur.col); //1.判斷當前點是否能落腳,不能落腳直接返回 if(!CanStay(maze,cur)){ return; } //2.如果能落腳,標記當前點 Mark(maze,cur); //3.判斷當前點是否為出口點,是則直接return if(IsExit(maze,cur,entry)){ //找到了出口直接返回 printf("找到了一條出路\n"); return; } //4.判斷當前點的上下左右是否有路可走,遞迴判斷 Point up = cur; up.row -= 1; _GetPath(maze,up,entry); Point right = cur; right.col += 1; _GetPath(maze,right,entry); Point down = cur; down.row += 1; _GetPath(maze,down,entry); Point left = cur; left.col -= 1; _GetPath(maze,left,entry); } void GetPath(Maze* maze,Point entry){ if(maze == NULL){ return; } //使用_GetPath輔助完成遞迴 _GetPath(maze,entry,entry); }
非遞迴版本
//////////////////////////////////////////////////////////////////////////////////////
// Round2 使用非遞迴版本
/////////////////////////////////////////////////////////////////////////////////////
void GetPathByLoop(Maze* maze,Point entry){
if(maze == NULL){
return;
}
SeqStackType cur;
//手動維護一個棧,儲存走過的路徑
SeqStack stack;
SeqStackInit(&stack);
//1.先判斷是否能落腳,能落腳,當前點入棧
if(!CanStay(maze,entry)){
return;
}
SeqStackPush(&stack,entry);
//2.如果能落腳,標記當前點
// Mark(maze,entry);
//迴圈取棧頂元素
while(SeqStackTop(&stack,&cur)){
Mark(maze,cur);
if(IsExit(maze,cur,entry)){
printf("找到了一條出路\n");
return;
}
Point up = cur;
up.row -= 1;
if(CanStay(maze,up)){
// Mark(maze,up);
SeqStackPush(&stack,up);
continue;
}
Point right = cur;
right.col += 1;
if(CanStay(maze,right)){
// Mark(maze,right);
SeqStackPush(&stack,right);
continue;
}
Point down = cur;
down.row += 1;
if(CanStay(maze,down)){
// Mark(maze,down);
SeqStackPush(&stack,down);
continue;
}
Point left = cur;
left.col -= 1;
if(CanStay(maze,left)){
// Mark(maze,left);
SeqStackPush(&stack,left);
continue;
}
SeqStackPop(&stack);
}
}
測試程式碼
//////////////////////////////////////////////////////////////////////////////////////
// 以下為測試程式碼
/////////////////////////////////////////////////////////////////////////////////////
#if 1
#define TEST_HEADER printf("\n=========================%s=======================\n",__FUNCTION__)
void test(){
TEST_HEADER;
Maze maze;
MazeInit(&maze);
MazePrint(&maze);
Point entry = {0,1};
GetPath(&maze,entry);
MazePrint(&maze);
}
void test2(){
TEST_HEADER;
Maze maze;
MazeInit(&maze);
MazePrint(&maze);
Point entry = {0,1};
GetPathByLoop(&maze,entry);
MazePrint(&maze);
}
int main(){
test();
test2();
return 0;
}
#endif