生成迷宫的深度优先遍历算法的非递归实现

来源:互联网 发布:js中如何隐藏div 编辑:程序博客网 时间:2024/05/22 14:16

一.算法分析:

生成一张二维单路径迷宫图,可以想到的方法之一就是图的遍历。因为单路径顾名思义就是要求每个节点能切只能访问一次,这正好和图的遍历方法一样。其次就是图的遍历保证了只有一条路径。

①首先创建一个二维数组,char maze[H][W],其中H和W必须是奇数,创建一个空间足够大的栈stack[H*W];

②初始化maze将四周存入‘w’(表示墙的意思),中间的存入‘n'(表示还未被访问的意思,中间的数组共有三种状态’n',‘y':已经被访问,’r':将要被访问)

③开始从maze[1][1]进行循环,首先判断可以访问的方向,然后随机产生一个方向,进行入栈,如果没有可以访问的方向则开始出栈,直到栈为空,跳出循环。



二.C语言实现(附加走迷宫函数path())

#include <stdio.h>#include <stdlib.h>#include <windows.h>#include <time.h>#define H 11//高#define W 11//宽#define MAX 121//栈的深度H和W的乘积typedef struct path {COORD cell;struct path *pro;struct path *next;}PATH;void inimaze(char maze[H][W])//初始化函数{int i, j;//i高度j宽度for (i = 1; i<H; i++){for (j = 1; j<W - 1; j++){maze[i][j] = 'n';//n表示没有被访问y表示已被访问r表示准备访问w表示墙}}//设置墙for (i = 0; i<H; i++){maze[i][0] = 'w';maze[i][W - 1] = 'w';}for (j = 0; j<W; j++){maze[0][j] = 'w';maze[H - 1][j] = 'w';}}void creatmaze(char maze[H][W])//生成迷宫的函数{srand(time(NULL));COORD stack[MAX];int head = -1;//需要的工具栈int i = 1, j = 1;//当前坐标head++;stack[head].X = i;stack[head].Y = j;maze[i][j] = 'y';//进入循环前的准备char dir[4], c;//用于存放有几个方向可以访问int k, m, t;//k用于初始化dir[],m+1是方向的个数,for (k = 0; k <= 3; k++){dir[k] = '\0';//u d l r}while (head != -1)//while中有四个模块分别对应的①判断有多少个方向可以访问 ②随机访问一个方向 ③当没有访问的方向后开始退栈{m = -1;if ((maze[i+1][j]!='w' && maze[i + 2][j] == 'n') || maze[i + 2][j] == 'r'){maze[i + 2][j] = 'r';m++;dir[m] = 'd';}if ((maze[i-1][j]!='w' && maze[i - 2][j] == 'n') || maze[i - 2][j] == 'r'){maze[i - 2][j] = 'r';m++;dir[m] = 'u';}if ((maze[i][j+1]!='w' && maze[i][j + 2] == 'n') || maze[i][j + 2] == 'r'){maze[i][j + 2] = 'r';m++;dir[m] = 'r';}if ((maze[i][j-1]!='w' && maze[i][j - 2] == 'n') || maze[i][j - 2] == 'r'){maze[i][j - 2] = 'r';m++;dir[m] = 'l';}//以上四个if语句得出两个结果m:可以走的方向个数,dir[]:具体的可走的方向if (m >= 0){t = rand() % (m + 1);//随机的方向c = dir[t];switch (c){case 'u':maze[i - 1][j] = 'y';i -= 2;maze[i][j] = 'y';break;case 'd':maze[i + 1][j] = 'y';i += 2;maze[i][j] = 'y';break;case 'r':maze[i][j + 1] = 'y';j += 2;maze[i][j] = 'y';break;case 'l':maze[i][j - 1] = 'y';j -= 2;maze[i][j] = 'y';break;}head++;stack[head].X = i;stack[head].Y = j;}//这一个if语句目的是随机访问下一个节点if (m == -1){head--;i = stack[head].X;j = stack[head].Y;}//如果m=-1;说明走投无路开始退栈}}void print_maze(char maze[H][W]){int i, j;char c;for (i = 0; i<H; i++){for (j = 0; j<W; j++){c = maze[i][j];if (c == 'y'){printf("  ");}else{printf("█");}}printf("\n");}printf("\n\n");}void print_maze2(char maze[H][W])//此函数纯属调试的时候看二维数组中的状态{int i, j;char c;for (i = 0; i<H; i++){for (j = 0; j<W; j++){c = maze[i][j];if (c == 'y'){printf("%c", c);}else{printf("%c", c);}}printf("\n");}printf("\n\n");}void putout_file(char maze[H][W]){int i, j,ch;FILE *fp;if ((fp=fopen("maze.data", "a+")) == NULL){fp=fopen("maze.data", "w+");}for (i = 0; i < H; i++ ){for (j = 0; j < W; j++ ){if (maze[i][j] == 'y'){ch = 'O';}else{ch = '*';}putc(ch, fp);}putc('\n', fp);}putc('\n\n\n', fp);fclose(fp);}void path(char maze[H][W],PATH *head)//*********此函数会破坏迷宫数组将其中的y用Y代替**********此函数在最后使用{head = (PATH *)malloc(sizeof(PATH));PATH *p = head;//初始化head->cell.X = 1;head->cell.Y = 1;head->pro = NULL;head->next = NULL;//存储方向的数组int m;char dir[4],ch;maze[1][1] = 'Y';while ((p->cell.X != H - 2) || (p->cell.Y != W - 2)){for (m = 0; m < 4; m++){dir[m] = '\0';}m = -1;if (maze[p->cell.X - 1][p->cell.Y] == 'y'){m++;dir[m] = 'u';}if (maze[p->cell.X + 1][p->cell.Y] == 'y'){m++;dir[m] = 'd';}if (maze[p->cell.X][p->cell.Y - 1]=='y'){m++;dir[m] = 'l';}if (maze[p->cell.X][p->cell.Y+1] == 'y'){m++;dir[m] = 'r';}//判断可走的方向if (m >= 0){p->next = (PATH *)malloc(sizeof(PATH));p->next->cell.X = p->cell.X;p->next->cell.Y = p->cell.Y;p->next->pro = p;p->next->next = NULL;//把当前位置继承下来并且初始化nextp = p->next;srand(time(NULL));ch = dir[rand() % (m + 1)];switch (ch){case 'u':p->cell.X -= 1;maze[p->cell.X][p->cell.Y] = 'Y';break;case 'd':p->cell.X += 1;maze[p->cell.X][p->cell.Y] = 'Y';break;case 'l':p->cell.Y -= 1;maze[p->cell.X][p->cell.Y] = 'Y';break;case 'r':p->cell.Y += 1;maze[p->cell.X][p->cell.Y] = 'Y';break;}}else{//maze[p->cell.X][p->cell.Y] = 'y';p = p->pro;free(p->next);p->next = NULL;}}p = head;while (p != NULL){printf("(%d,%d)",p->cell.X,p->cell.Y);p = p->next;}printf("\n");}int main(){char maze[H][W];PATH *head = NULL;inimaze(maze);creatmaze(maze);print_maze(maze);putout_file(maze);path(maze, head);print_maze2(maze);Sleep(5000);return 0;}


阅读全文
0 0