"迷宫问题(栈)"
“栈”是一种简单的数据结构,它的主要特点就是"先进后出",即就是先压入栈中的数据需要最后出栈。相当于栈是一个杯子,最先放进栈中的东西,只能够最后拿出来。下面对“栈”的特点用图形象的表示出来。
这次所要讨论的是基于栈的迷宫问题,当给定一个迷宫,我们怎样能够找出迷宫中的通道呢?如果迷宫的规模比较大,我们又该如何去实现呢?我们能够明显的知道需要使用一个二维数组用来保存迷宫,但是当迷宫的规模比较大时,或者是当我们想要频繁的去更改所设计的迷宫时,用二维数组的方式显然是不大合理,程序更改会比较麻烦。
在这里我采用“文件”的方式将迷宫进行保存,程序中只用实现读取文件的操作,这样很便于以后对程序的维护。因为动态的给定迷宫大小,程序的实现还是较为麻烦的,这里直接将迷宫的规模给定。用“1”来表示不能够通过,“0”表示能够通过。下面是迷宫的设计:
针对迷宫的特点,主要采用的方法是先将迷宫的入口点压入栈中,在对这个点的上、下、左、右方向的节点进行判断,看是否有能够通过的节点(“0”),若没有,则迷宫中没有一条能够通过的路径,如果存在,则将这个节点也压入栈中,循环这种方式,直到找到没有能够前进的点,此时就要进行“回溯”, 即就是倒回以前走过的点。进而在判断有没有刚才没有走过的且能够通过的节点,若存在,再次进行刚才的压栈操作,直到走出迷宫,若回到迷宫的入口点,则迷宫中不存在通路。
根据上面的思路,编写出下面的代码:
//memory.h文件 #pragma once #define MAX 10 #include <stack> #include <assert.h> //使用静态数组 struct pos //标记点的位置坐标 { int _row; int _col; }; void GetMaze(int * arr, int n) //从文件中获取迷宫 { assert(arr); FILE* open = fopen("F:\\keshe\\迷宫问题(栈)\\MazeMap.txt", "r"); assert(open); //判断打开文件是否成功 for (int i = 0; i < MAX; i++) { for (int j = 0; j < MAX; ) { char ch = fgetc(open); if (ch == ‘1‘ || ch == ‘0‘) { arr[i * n + j] = ch - ‘0‘; j++; //为了防止迷宫中行与列之间的间距 } } } fclose(open); } void print(int * arr, int n) //打印迷宫 { for (int i = 0; i < MAX; i++) { for (int j = 0; j < MAX; j++) { cout << arr[i * n + j] << " "; } cout << endl; } } bool checkIsAccess(int * arr, int n, const pos& next) //检查迷宫节点的下一个路径上的节点 { assert(arr); if (next._row >= 0 && next._row < MAX && next._col >= 0 && next._col <= MAX && arr[next._row * n + next._col] == 0) { return true; } return false; } //entry 为入口的位置,Paths用来保存迷宫的通路 //判断迷宫中是否存在一条通路 bool SearchMazePaths(int * arr, int n, pos entry, stack<pos> & Paths) { assert(arr); Paths.push(entry); while (!Paths.empty()) { pos cur = Paths.top(); arr[cur._row * n + cur._col] = 2; //将压栈后的位置内容进行更改 if (cur._row == (n - 1)) { return true; } pos next = cur; //上 next._row--; if (checkIsAccess(arr, n, next)) { Paths.push(next); continue; } //下 next = cur; next._row++; if (checkIsAccess(arr, n, next)) { Paths.push(next); continue; } //左 next = cur; next._col--; if (checkIsAccess(arr, n, next)) { Paths.push(next); continue; } //右 next = cur; next._col++; if (checkIsAccess(arr, n, next)) { Paths.push(next); continue; } Paths.pop(); //若节点的剩余方向都不能通过,则进行回溯。 } }
//test.cpp文件 #define _CRT_SECURE_NO_WARNINGS 1 //使用栈来设计迷宫问题 #include <iostream> using namespace std; #include <stdlib.h> #include "memory.h" int main() { int arr[MAX][MAX] = { 0 }; stack<pos> Paths; pos tmp; tmp._row = 2; tmp._col = 0; GetMaze((int*)arr, MAX); print((int*)arr, MAX); cout << endl << endl; int ret = SearchMazePaths((int *)arr, MAX, tmp, Paths); printf("能否有一条通路:%d\n\n\n", ret); print((int*)arr, MAX); system("pause"); return 0; }
时间: 2024-12-28 01:41:56