数据结构与算法学习之路:迷宫问题——回溯思想找出所有路径
今天小伙伴和我说之前写的那个迷宫问题有些问题,我就改了改,感觉之前写的东西思路也不清晰,也比较乱,就重新写了一篇……别在意哈~
一、迷宫问题描述:
给定一个迷宫,以及起点和终点,通过设计算法,找到一条可以到达终点的路径。解决以后,想办法找到最短路径和所有路径。
二、解决方法:
1、找到一条可达的路径并不难,只要设定方向,然后每个点都去找一个可以走的方向一直向可行方向走就是了。
2、找到最短路径。要找到最短路径,可以尝试广度优先算法——BFS。BFS找图中一点到另一点的最短路径还是很方便的(没有权值),主要思想是,把每一个点可到的状态都算出来,最先到达终点的状态就是最短的路径长度。就这样说可能很抽象,不妨看看下面这张图:
3、找所有路径。找所有路径比较简单的方法是先找出一条路径,然后回溯到上一个点,看看有没有别的地方可以走,再从这个方向往下走。从而不断回溯找到所有路径
三、代码:
找到所有路径的实现方式:
#include <stdio.h> #include <stdlib.h> #define WALL 1 #define ROAD 0 #define END -1 #define TRUE 1 #define FALSE 0 #define VISITED 1 #define UNVISITED 0 #define BARRIER -1 //四周都是墙的死路 #define MAXSIZE 11 //迷宫每行或每列中点的的最大数量 #define DIR_SIZE 4 //方向 #define STACK_SIZE 128 typedef int Status; //迷宫中的点 typedef struct Point{ int x; int y; Status status; Status visited; }Point; typedef struct Stack{ Point point[STACK_SIZE]; int top; }Stack, *StackPtr; void Stack_Init(StackPtr s); void Stack_Push(StackPtr s, Point point); void Stack_Pop(StackPtr s); //搜索所有路径。 //多入口多出口加个起点终点数组,将起点通过循环作为栈底,遍历到达不同终点的路径即可 void Maze_Search(StackPtr s, Point maze[MAXSIZE][MAXSIZE],Point *dir); int main(){ StackPtr stack; Point dir[DIR_SIZE]; Point up, down, right, left; Point maze[MAXSIZE][MAXSIZE]; int i, j; //初始化迷宫 for (i = 0; i < MAXSIZE; i++){ for (j = 0; j < MAXSIZE; j++) maze[i][j].status = ROAD; } for (i = 0; i < MAXSIZE; i++) for (j = 0; j < MAXSIZE; j++){ maze[i][j].x = i; maze[i][j].y = j; maze[i][j].visited = UNVISITED; } for (i = 0; i < MAXSIZE; i++){ maze[0][i].status = WALL; maze[10][i].status = WALL; maze[0][i].visited = VISITED; maze[10][i].visited = VISITED; } for (i = 0; i < MAXSIZE; i++){ maze[i][0].status = WALL; maze[i][10].status = WALL; maze[i][0].visited = VISITED; maze[i][10].visited = VISITED; } maze[1][2].status = WALL; maze[1][3].status = WALL; maze[1][5].status = WALL; maze[1][6].status = WALL; maze[1][9].status = WALL; maze[2][3].status = WALL; maze[2][4].status = WALL; maze[2][7].status = WALL; maze[2][8].status = WALL; maze[2][9].status = WALL; maze[3][3].status = WALL; maze[3][5].status = WALL; maze[3][6].status = WALL; maze[3][8].status = WALL; maze[4][2].status = WALL; maze[4][4].status = WALL; maze[4][7].status = WALL; maze[4][9].status = WALL; maze[5][6].status = WALL; maze[5][3].status = WALL; maze[5][5].status = WALL; maze[5][8].status = WALL; maze[6][1].status = WALL; maze[6][4].status = WALL; maze[6][6].status = WALL; maze[6][7].status = WALL; maze[6][9].status = WALL; maze[7][4].status = WALL; maze[7][8].status = WALL; maze[7][9].status = WALL; maze[8][2].status = WALL; maze[8][6].status = WALL; maze[9][1].status = WALL; maze[9][2].status = WALL; maze[1][1].visited = VISITED; maze[1][2].visited = VISITED; maze[1][3].visited = VISITED; maze[1][5].visited = VISITED; maze[1][6].visited = VISITED; maze[1][9].visited = VISITED; maze[2][3].visited = VISITED; maze[2][4].visited = VISITED; maze[2][7].visited = VISITED; maze[2][8].visited = VISITED; maze[2][9].visited = VISITED; maze[3][3].visited = VISITED; maze[3][5].visited = VISITED; maze[3][6].visited = VISITED; maze[3][8].visited = VISITED; maze[4][2].visited = VISITED; maze[4][4].visited = VISITED; maze[4][7].visited = VISITED; maze[4][9].visited = VISITED; maze[5][6].visited = VISITED; maze[5][3].visited = VISITED; maze[5][5].visited = VISITED; maze[5][8].visited = VISITED; maze[6][1].visited = VISITED; maze[6][4].visited = VISITED; maze[6][6].visited = VISITED; maze[6][7].visited = VISITED; maze[6][9].visited = VISITED; maze[7][4].visited = VISITED; maze[7][8].visited = VISITED; maze[7][9].visited = VISITED; maze[8][2].visited = VISITED; maze[8][6].visited = VISITED; maze[9][1].visited = VISITED; maze[9][2].visited = VISITED; maze[9][9].status = END; up.x = -1; up.y = 0; up.status = ROAD; left.x = 0; left.y = -1; left.status = ROAD; right.x = 0; right.y = 1; right.status = ROAD; down.x = 1; down.y = 0; down.status = ROAD; dir[0] = left; dir[1] = down; dir[2] = right; dir[3] = up; //输出迷宫 for (i = 0; i < MAXSIZE; i++){ for (j = 0; j < MAXSIZE; j++){ if (maze[i][j].status == WALL) printf("▇"); else printf(" "); } printf("\n"); } printf("\n"); //初始化保存路径的栈 stack = (StackPtr)malloc(sizeof(Stack)); Stack_Init(stack); Maze_Search(stack, maze, dir); return 0; } void Stack_Init(StackPtr s){ Point temp; if (s == NULL) return; temp.x = 1; temp.y = 1; temp.status = ROAD; temp.visited = VISITED; s->top = 0; s->point[s->top] = temp; return; } void Stack_Push(StackPtr s, Point point){ if (s->top == (STACK_SIZE - 1)){ printf("栈已满!"); return; } s->top += 1; s->point[s->top] = point; } void Stack_Pop(StackPtr s){ Point temp; if (s->top == -1){ printf("栈为空!"); return; } temp.x = 0; temp.y = 0; temp.status = ROAD; s->point[s->top] = temp; s->top -= 1; } void Maze_Search(StackPtr s, Point maze[MAXSIZE][MAXSIZE],Point *dir){ int i,j; if (s->point[s->top].status == END){ for (i = 0; i < MAXSIZE; i++){ for (j = 0; j < MAXSIZE; j++){ if (maze[i][j].status == WALL) printf("▇"); else if ((maze[i][j].status == ROAD || maze[i][j].status == END) && maze[i][j].visited == VISITED && maze[i][j].visited != BARRIER) printf("※"); else printf(" "); } printf("\n"); } maze[9][9].visited = UNVISITED; Stack_Pop(s); printf("\n\n"); return; } for (i = 0; i < DIR_SIZE; i++){ if (maze[s->point[s->top].x + dir[i].x][s->point[s->top].y + dir[i].y].status != WALL && maze[s->point[s->top].x + dir[i].x][s->point[s->top].y + dir[i].y].visited != VISITED){ maze[s->point[s->top].x + dir[i].x][s->point[s->top].y + dir[i].y].visited = VISITED; Stack_Push(s, maze[s->point[s->top].x + dir[i].x][s->point[s->top].y + dir[i].y]); Maze_Search(s, maze, dir); } } for (i = 0; i < DIR_SIZE; i++){ if (maze[s->point[s->top].x + dir[i].x][s->point[s->top].y + dir[i].y].status != WALL && maze[s->point[s->top].x + dir[i].x][s->point[s->top].y + dir[i].y].visited != VISITED){ maze[s->point[s->top].x][s->point[s->top].y].visited = UNVISITED; Stack_Pop(s); return; } } if (maze[s->point[s->top].x][s->point[s->top].y - 1].status == ROAD && maze[s->point[s->top].x][s->point[s->top].y - 1].visited == UNVISITED) maze[s->point[s->top].x][s->point[s->top].y].visited = UNVISITED; maze[s->point[s->top].x][s->point[s->top].y].visited = BARRIER; Stack_Pop(s); return; }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。