迷宫求解(递归)

首先来看一下迷宫简易图
                            这里写图片描述
    我们用 0 来表示该位置是墙, 用 1 来表示该位置是路. 所以, 我们在处理迷宫问题的时候可以将其看成一个二维数组即可, 而对应的每一条路我们可以用坐标的形式将其表示, 所以还需要有一个结构体来描述对应的点的
1. 相关数据结构

typedef struct Maze 
{int map[MAX_ROW][MAX_COL];
}Maze;
typedef struct Point
{int row;int col;
}Point;

2.迷宫初始化
    所谓的初始化迷宫就是将这个二维数组初始化, 我们自己定义一个二维数组, 然后将其每一个值赋值给我们的迷宫地图即可

void MazeInit(Maze* maze)
{if(maze == NULL){return;}int Map[MAX_ROW][MAX_COL] = {{0, 1, 0, 0, 0, 0},{0, 1, 0, 0, 0, 0},{0, 1, 0, 0, 0, 0},{0, 1, 1, 1, 1, 0},{0, 0, 0, 1, 1, 0},{0, 0, 0, 1, 0, 0}};int row = 0;int col = 0;for(; row < MAX_ROW; row++){for(col = 0; col < MAX_COL; col++){maze -> map[row][col] = Map[row][col];}}
}

3.迷宫探索
    迷宫探索即就是从给出的迷宫入口开始, 一直往后探索, 直到找到出口为止. 我们利用函数在递归的过程中会形成栈桢的特性, 依次将我们所探索的为位置进行压栈, 在此过程中, 我们必须得判断当前的点是否合法, 同时必须判断当前的点是否可以落脚, 如果可以落脚, 就现将该位置标记, 然后判断当前位置是否是出口, 如果是出口, 说明迷宫探索完毕, 如果不是出口, 那么我们就得必须找下一个可以落脚的位置, 即我们依次按照顺时针的方向依次遍历当前位置四周的四个点(up, rught, down, left), 只要我们发现有一个点可以落脚, 我们就将当前位置对应的点入栈(调用函数本身), 当四个方向都已经走完了, 那么我们就得往回退, 即就是对应的出栈过程了.具体如下图
                                    这里写图片描述

void _GetPath(Maze* maze, Point cur, Point entry)
{if(maze == NULL){return;}if(cur.row < 0 || cur.row >= MAX_ROW || cur.col < 0 || cur.col > MAX_COL){return;}if(entry.row < 0 || entry.row >= MAX_ROW || entry.col < 0 || entry.col >= MAX_COL){return;}printf("(%d, %d)\n", cur.row, cur.col);//判断当前点是否可以落脚if(CanStay(maze, cur))//如果可以落脚, 就给当前位置标记//如果当前点是出口, 则说明找到了一条路按顺时针方向探测四个相邻点, 递归调用函数自身, {Mark(maze, cur);if(IsExit(maze, cur, entry)){printf("找到了一条路\n");return;}//递归时更新 cur, (每次递归时, 这里的点是下次要走的点, 无论能不能走交给递归判断)Point up = cur;up.row -= 1;_GetPath(maze, up, entry);Point right = cur;right.col += 1;_GetPath(maze, right, entry);Point down = cur;down.row += 1;_GetPath(maze, down, entry);Point left = cur;left.col -= 1;_GetPath(maze, left, entry);}else{return;}
}void GetPath(Maze* maze, Point entry)
{if(maze == NULL){return;//非法输入}if(entry.row < 0 || entry.row >= MAX_ROW || entry.col < 0 || entry.col >= MAX_COL){return;}//辅助完成递归_GetPath(maze, entry, entry);MazePrint(maze);
}

4.判断是否可以落脚
     即先判断迷宫数据结构是否输入合法, 接下来就是判断当前位置是否合法, 如果不合法就退出, 如果当前位置对应的值是 1, 则说明能落脚, 否则就说明不能落脚.

int CanStay(Maze* maze, Point cur)
{if(maze == NULL){return 0;}if(cur.row < 0 || cur.row >= MAX_ROW || cur.col < 0 || cur.col >= MAX_COL){return 0;}if(maze -> map[cur.row][cur.col] == 1){return 1;}return 0;
}

5.判断出口
    如果该位置到达迷宫边界, 并且不等于入口位置, 则说明到达出口

int IsExit(Maze* maze, Point cur, Point entry)
{if(maze == NULL){return 0;}if(cur.row == entry.row && cur.col == entry.col){return 0;}if(cur.row == MAX_ROW -1 || cur.row == 0 || cur.col ==MAX_COL -1 || cur.col == 0){return 1;}return 0;
}

6.标记
    将当前位置的值赋值为2

void Mark(Maze* maze, Point cur)
{if(maze == NULL){return;}if(cur.row < 0 || cur.row >= MAX_ROW || cur.col < 0 || cur.col >= MAX_COL){return;}maze -> map[cur.row][cur.col] = 2;
}

7.打印迷宫函数

void MazePrint(Maze* maze)
{if(maze == NULL){return;//非法输入}int row = 0;int col = 0;for(; row < MAX_ROW; row++){for(col = 0; col < MAX_COL; col++){printf("%2d ", maze -> map[row][col]);}printf("\n");}
}

    依次将回溯点打印出来,运行结果如图
                                这里写图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/384045.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构练习——双向链表

http://www.cnblogs.com/-Lei/archive/2012/04/10/2440399.html 复习一下数据结构。。。。说不准下个星期就用上了 只不过写的很简单&#xff0c;没有封装 DoubleLinkList.h #ifndef GUARD_DoubleLinkList_h #define GUARD_DoubleLinkList_h#include <stdio.h>struct Li…

线程的终止分离

1.线程的终止 注意该函数是针对用户级别的, 其中 retal 必须指向一个全局变量, 或者是一个 malloc 分配的, 因为如果是线程的局部变量, 当该线程退出时, 其他线程不能得到这个变量, 因为线程的局部变量各自私有 2. 现成的取消 其中thread是线程的 tid 3.线程的等待与分离 (1)…

C语言中的深拷贝和浅拷贝

http://www.cnblogs.com/zhanggaofeng/p/5421804.html C语言中的深拷贝和浅拷贝 //C语言中的深拷贝和浅拷贝 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h>typedef struct _student{char name[30];char *title;…

死锁的产生和避免

1.死锁产生的四个必要条件 (1)互斥条件&#xff1a;资源是独占的且排他使用&#xff0c;进程互斥使用资源&#xff0c;即任意时刻一个资源只能给一个进程使用&#xff0c;其他进程若申请一个资源&#xff0c;而该资源被另一进程占有时&#xff0c;则申请者等待直到资源被占有者…

gethostbyname() 函数说明

https://www.cnblogs.com/cxz2009/archive/2010/11/19/1881611.html gethostbyname()函数说明——用域名或主机名获取IP地址 包含头文件#include <netdb.h>#include <sys/socket.h>函数原型struct hostent *gethostbyname(const char *name);这个函数的传入值是域…

求解迷宫最短路径

1. 多通路迷宫初始化 先构建一个多通路迷宫,并且对其初始化 void MazeInitShortPath(Maze* maze) {if(maze NULL){return;}int row 0;int col 0;for(; row < MAX_COL; row){for(col 0; col < MAX_COL; col){maze -> map[row][col] Map[row][col];}printf("…

带环迷宫求最短路径

前面介绍了简单的迷宫求解问题, 今天我们就对带环迷宫求出它的最短路径 1.首先来看一个带环迷宫的简单地图 在这张迷宫地图中,我们规定入口点的位置entry的坐标是 (0, 1), 同时, 我们给入口点传一个非法坐标,作为入口点的前一个位置(-1, -1). 接下来的思路就和上一篇的思路是一…

线程的同步与互斥

1. 互斥量 在Linux 下线程使用的都是局部变量, 而我们知道, 每一个线程都独立拥有自己的一个栈, 而这些局部便令就在栈中,而线程的创建就是为了实现通信, 此时线程之间无法共享这些变量     为了使得线程之间能够共享数据, 一次我们可以创建一个全局变量, 此时线程都在进程…

C语言 可变参数

http://www.cnblogs.com/zhanggaofeng/p/6434554.html //可变参数 #include <stdio.h> #include <stdlib.h> #include <string.h> //引用头文件 #include <stdarg.h>/* va_list用于声明一个变量&#xff0c;我们知道函数的可变参数列表其实就是一个字符…

c语言经典算法——查找一个整数数组中第二大数

https://www.cnblogs.com/dootoo/p/4473958.html 题目&#xff1a; 实现一个函数&#xff0c;查找一个整数数组中第二大数。 算法思想&#xff1a; 设置两个变量max1和max2&#xff0c;用来保存最大数和第二大数&#xff0c;然后将数组剩余的数依次与这两个数比较&#xff0c;如…

进程间关系和守护进程

一. 进程组/作业/会话 1.进程组 每一个进程除了有一个进程ID之外, 还属于一个进程组. 进程是一个或多个进程的集合. 通常, 它们与同一个作业向关联, 可以接收来自同一个终端下的各种命令,信号. 每一个进程组都有唯一的进程组 ID. 每一个进程组都可以有一个组长进程. 组长进程的…

猴子偷桃问题

http://blog.csdn.net/snow_5288/article/details/52561882 问题描述&#xff1a; /*有一群猴子&#xff0c;去摘了一堆桃子*/ /*商量之后决定每天吃剩余桃子的一半*/ /*当每天大家吃完桃子之后&#xff0c;有个贪心的小猴都会偷偷再吃一个桃子*/ /*按照这样的方式猴子们每天都…

网络相关基础概念

一. 相关基础概念 1.计算机网络的特点 (1)连通性:计算机网络使得上网的用户都能够彼此相连, 好像用户的计算机可以直接相连     (2)资源共享:资源共享可以是信息共享, 软件共享, 硬件共享等等. 由于网络的存在, 使得用户感觉资源就在自己身边 2. 网络 网络是由若干结点和…

linux线程同步(2)-条件变量

https://www.cnblogs.com/yuuyuu/p/5140875.html linux线程同步(2)-条件变量 一.概述 上一篇&#xff0c;介绍了互斥量。条件变量与互斥量不同&#xff0c;互斥量是防止多线程同时访问共享的互斥变量来保护临界区。条件变量…

点对点数据链路层

数据链路层的主要功能将数据转换为相应的比特流使用的信道主要有点对点的信道方式(一对一的方式), 以及广播的信道方式 一. 点对点信道的数据链路层 1. 数据链路和数据帧 链路就是从一个结点连接到相邻结点的一段物理线路(有线或者无线), 期间不准有任何的交换结点, 因此两台…

linux线程同步(1)-互斥量

http://www.cnblogs.com/yuuyuu/p/5140251.html 一.概述 互斥量是线程同步的一种机制&#xff0c;用来保护多线程的共享资源。同一时刻&#xff0c;只允许一个线程对临界区进行访问。 互斥量的工作流程&#xff1a;创建一个…

linux线程同步(3)-读写锁

http://www.cnblogs.com/yuuyuu/p/5143881.html 一.概述 读写锁与互斥量的功能类似&#xff0c;对临界区的共享资源进行保护&#xff01;互斥量一次只让一个线程进入临界区&#xff0c;读写锁比它有更高的并行性。读写锁有…

linux线程同步(5)-屏障

http://www.cnblogs.com/yuuyuu/p/5152560.html 一.概述 barrier(屏障)与互斥量&#xff0c;读写锁&#xff0c;自旋锁不同&#xff0c;它不是用来保护临界区的。相反&#xff0c;它跟条件变量一样&#xff0c;是用来协同多…

Linux多线程与同步

https://www.cnblogs.com/freedomabcd/p/7774743.html 典型的UNIX系统都支持一个进程创建多个线程(thread)。在Linux进程基础中提到&#xff0c;Linux以进程为单位组织操作&#xff0c;Linux中的线程也都基于进程。尽管实现方式有异于其它的UNIX系统&#xff0c;但Linux的多线程…

内存管理(二)

页面置换算法 当发生缺页中断的时候, 系统会在内存中选择一个页面将其换出内存, 而当换出内存的时候如果该页面的内容在内存中发生修改,则必须将该新数据重新写回到磁盘, 然后再将需要换进的数据覆盖掉原来的数据, 而当该数据在内存中没有被修改的时候, 此时就直接用需要换进的…