生成迷宫的深度优先遍历算法的非递归实现
一.算法分析:
生成一张二维单路径迷宫图,可以想到的方法之一就是图的遍历。因为单路径顾名思义就是要求每个节点能切只能访问一次,这正好和图的遍历方法一样。其次就是图的遍历保证了只有一条路径。
运行后即如下图所示:
①首先创建一个二维数组,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;
- //把当前位置继承下来并且初始化next
- p = 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;
- }
- <span style="font-family:Arial, Helvetica, sans-serif;"><span style="white-space:normal;"></span></span>
一.算法分析:
生成一张二维单路径迷宫图,可以想到的方法之一就是图的遍历。因为单路径顾名思义就是要求每个节点能切只能访问一次,这正好和图的遍历方法一样。其次就是图的遍历保证了只有一条路径。
运行后即如下图所示:
①首先创建一个二维数组,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;
- //把当前位置继承下来并且初始化next
- p = 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;
- }
- <span style="font-family:Arial, Helvetica, sans-serif;"><span style="white-space:normal;"></span></span>