棧與佇列的應用——迷宮問題
阿新 • • 發佈:2019-02-02
在熟悉了棧的基本操作之後,本人試著解決了迷宮問題過程如下:
再次用的是回溯法解決。具體想了解去百度!!!!!
首先在標頭檔案裡定義了三種不同難度迷宮程式碼如下:
#pragma once #include "Stack.h" #define N 6 //static int maze[N][N] = { // {0,0,0,0,0,0}, // {0,0,1,0,0,0}, // {0,0,1,0,0,0}, // {0,0,1,1,1,0}, // {0,0,1,0,1,1}, // {0,0,1,0,0,0}, //}; //static int maze[N][N] = { // {0,0,0,0,0,0}, // {0,0,1,1,1,1}, // {0,0,1,0,0,0}, // {0,0,1,1,1,1}, // {0,0,1,0,0,0}, // {0,0,1,0,0,0}, //}; static int maze[N][N] = { {0,0,0,0,0,0}, {0,0,1,1,1,0}, {0,0,1,0,1,0}, {0,0,1,1,1,1}, {0,0,1,0,0,0}, {0,0,1,0,0,0}, }; int GetMazePath(Pos entry, Pos exit); void PrintMaze(); void TestMaze();
分別是:
一、只有一個出口的迷宮
二、含有多個出口的迷宮
三、帶環的迷宮
首先先列出前倆種迷宮的程式碼:
#include "Maze.h" int CheckAccess(Pos next) { if (next._row >= 0 && next._row < N && next._col >= 0 && next._col < N && maze[next._row][next._col] == 1) { return 1; } else { return 0; } } Stack minpath; int pathsize = 0; int GetMazePath(Pos entry, Pos exit) { Stack path; StackInit(&path); StackPush(&path, entry); while (StackEmpty(&path)) { Pos cur = StackTop(&path); Pos next; maze[cur._row][cur._col] = 2; //if (cur._row == exit._row // && cur._col == exit._col) if (cur._col == 5)//‘標記行’ { // 出口 // 如果只找一條通路,則返回 //StackDestory(&path); //return 1; //若要解決第一類迷宮問題,將上面註釋取消且將’標記行‘註釋即可 if(pathsize == 0 || StackSize(&path) < pathsize) { pathsize = StackSize(&path); } } // 探測下一個可以去的位置 // 上 next = cur; next._row -= 1; if (CheckAccess(next)) { StackPush(&path, next); continue; } // 下 next = cur; next._row += 1; if (CheckAccess(next)) { StackPush(&path, next); continue; } // 左 next = cur; next._col -= 1; if (CheckAccess(next)) { StackPush(&path, next); continue; } // 右 next = cur; next._col += 1; if (CheckAccess(next)) { StackPush(&path, next); continue; } // 回溯 StackPop(&path); } return 0; } void PrintMaze() { size_t i, j; for (i = 0; i < N; ++i) { for (j = 0; j < N; ++j) { printf("%d ", maze[i][j]); } printf("\n"); } printf("\n"); } void TestMaze() { Pos entry, exit; entry._row = 5; entry._col = 2; exit._row = 4; exit._col = 5; PrintMaze(); printf("是否有出口?:%d\n", GetMazePath(entry, exit)); printf("最短路徑:%d\n", pathsize); PrintMaze(); } void main() { TestMaze(); }
下面是第三類帶環迷宮程式碼:
#include "Maze.h" int CheckAccess(Pos cur, Pos next) { if ((next._row >= 0 && next._row < N && next._col >= 0 && next._col < N) && (maze[next._row][next._col] == 1 || maze[next._row][next._col] > maze[cur._row][cur._col] + 1)) { return 1; } else { return 0; } } Stack minpath; int pathsize = 0; int GetMazePath(Pos entry, Pos exit) { Stack path; StackInit(&path); StackPush(&path, entry); maze[entry._row][entry._col] = 2; while (StackEmpty(&path)) { Pos cur = StackTop(&path); Pos next; if (cur._col == 5) { if(pathsize == 0 || StackSize(&path) < pathsize) { pathsize = StackSize(&path); } } // 探測下一個可以去的位置 // 上 next = cur; next._row -= 1; if (CheckAccess(cur, next)) { maze[next._row][next._col] = maze[cur._row][cur._col]+1; StackPush(&path, next); continue; } // 下 next = cur; next._row += 1; if (CheckAccess(cur, next)) { maze[next._row][next._col] = maze[cur._row][cur._col]+1; StackPush(&path, next); continue; } // 左 next = cur; next._col -= 1; if (CheckAccess(cur, next)) { maze[next._row][next._col] = maze[cur._row][cur._col]+1; StackPush(&path, next); continue; } // 右 next = cur; next._col += 1; if (CheckAccess(cur, next)) { maze[next._row][next._col] = maze[cur._row][cur._col]+1; StackPush(&path, next); continue; } // 回溯 StackPop(&path); } return 0; } void PrintMaze() { size_t i, j; for (i = 0; i < N; ++i) { for (j = 0; j < N; ++j) { printf("%d ", maze[i][j]); } printf("\n"); } printf("\n"); } void TestMaze() { Pos entry, exit; entry._row = 5; entry._col = 2; exit._row = 4; exit._col = 5; PrintMaze(); printf("是否有出口?:%d\n", GetMazePath(entry, exit)); printf("最短路徑:%d\n", pathsize); PrintMaze(); } void main() { TestMaze(); }
在此附上迷宮所需棧的程式碼:
//標頭檔案------------------------------------------------------------------------------------
#pragma once
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <stdlib.h>
//typedef int DataType;
//
//#define N 10
//typedef struct Stack
//{
// DataType _a[N];
// int _top; // 棧頂
//}Stack;
typedef struct Pos
{
int _row;
int _col;
}Pos;
typedef Pos DataType;
typedef struct Stack
{
DataType* _a;
int _top; // 棧頂
int _capacity; // 容量
}Stack;
void StackInit(Stack* ps);
void StackDestory(Stack* ps);
void StackPush(Stack* ps, DataType x);
void StackPop(Stack* ps);
DataType StackTop(Stack* ps);
int StackEmpty(Stack* ps);
int StackSize(Stack* ps);
void StackPrint(Stack * ps);
void TestStack();
----------------------------------------------------------------------------------------
函式檔案---------------------------------------------------------------------------------
#include "Stack.h"
void StackInit(Stack* ps)
{
assert(ps);
ps->_a = (DataType*)malloc(sizeof(DataType));
assert(ps->_a);
ps->_top = 0;
ps->_capacity = 1;
}
void StackDestory(Stack* ps)
{
assert(ps);
if(ps->_a)
{
free(ps->_a);
ps->_a = NULL;
ps->_top = 0;
ps->_capacity = 0;
}
}
void StackPush(Stack* ps,DataType x)
{
assert(ps);
if(ps->_top == ps->_capacity)
{
ps->_a = realloc(ps->_a,2*ps->_capacity*sizeof(DataType));
ps->_capacity *= 2;
}
ps->_a[ps->_top] = x;
ps->_top++;
}
void StackPop(Stack* ps)
{
assert(ps->_a);
assert(ps->_top > 0);
ps->_top--;
}
DataType StackTop(Stack* ps)
{
assert(ps->_a && ps->_top > -1);
return ps->_a[ps->_top-1];
}
//空 0
//非空 1
int StackEmpty(Stack* ps)
{
assert(ps);
return ps->_top == 0 ? 0 :1;
}
int StackSize(Stack* ps)
{
return ps->_top;
}
void StackPrint(Stack *ps)
{
int i;
if(ps->_top == 0)
{
printf("棧為空,無法列印\n");
return ;
}
printf("棧內容為:");
for(i=ps->_top-1;i>=0;i--)
{
printf("%d ",ps->_a[i]);
}
printf("\n");
}
----------------------------------------------------------------------------------------