C语言之走迷宫深度和广度优先(利用堆栈和队列)

完成以下迷宫
利用二维数组储存每一个数组里的值,若是不能走则为1,若是可行就是0,走过了就设为2。
一般是再复制一个数组,用来记录。
堆栈的思想就是将一个点的上下左右都遍历一遍,若可行进栈,跳出遍历,再寻找下一个可走的。若遇到无路可走的就退回上一步,就是出栈。所以就是说堆栈里记录的是可以走到终点的路。
队列的思想就是一直找,把所有可以走的路都走一遍,直到遇到终点。
这里的每一个可以走的点都为链表中的一个节点,在队列中要记录这个点的上一点是什么,就是哪一个点衍生出的这个点。
若是堆栈,最后在出栈便是所走的路径,但是堆栈是后进先出的原理,可能为了好看最后要做些处理。
若是队列,最后是利用找到的终点的那个节点,一直找这个节点的上一个节点,上个节点的上个节点,一直找到起点,可能为了好看最后还是要做些处理。
这里就是按照上述方法做的,但是太懒了,做出来就没有处理了。
堆栈是比较简单的,主要是队列中的头部和尾部的节点设置,和进队列的时候是怎么循环,这个循环是怎么在遍历之前的节点的也同时在加入新的节点进队。后来我是没有用出队这个原理去做。
以下是用堆栈实现的
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
typedef struct stack{
int x;//记录下标
int y;
int direction;//记录方向
struct stack *next;
}stack;
int main(){
int maze[10][10];
int i,j;
for(i=0;i<10;i++){
for(j=0;j<10;j++){
if(i==0 || j==0 || i==9|| j==9){
maze[i][j]=1;
} else{
maze[i][j]=0;
}
}
}
maze[1][3]=1;
maze[1][7]=1;
maze[2][3]=1;
maze[2][7]=1;
maze[3][5]=1;
maze[3][6]=1;
maze[4][2]=1;
maze[4][3]=1;
maze[4][4]=1;
maze[5][4]=1;
maze[6][2]=1;
maze[6][6]=1;
maze[7][2]=1;
maze[7][3]=1;
maze[7][4]=1;
maze[7][6]=1;
maze[7][7]=1;
maze[8][1]=1;
//这里是输进去的迷宫,也可以随机实现,但是这里偷下懒
int cmaze[10][10];
for(i=0;i<10;i++){
for(j=0;j<10;j++){
cmaze[i][j]=maze[i][j];
}
}
//用一个新的二维数组记录走过的点
printf("\n\n");
stack *top,*p,*q,*t,*s;
top=(stack *)malloc(sizeof(stack));
top->next=NULL;
//人为设置的,(1,1)是起点,(8,8)是终点
int flag=0,x=0,y=0;
if(flag==0){
p=(stack *)malloc(sizeof(stack));
p->x=1;
p->y=1;
p->direction=-1;
q=top->next;
top->next=p;
p->next=q;
flag=1;
}
q=top->next;
x=q->x;
y=q->y;
while(q->x!=8 || q->y!=8){
//0:向左 y+1 1:向下 x+1 2:向右 y-1 3:向上 x+1
if(cmaze[x][y+1]==0){
p=(stack *)malloc(sizeof(stack));
p->x=x;
p->y=y+1;
p->direction=0;
q=top->next;
top->next=p;
p->next=q;
cmaze[x][y+1]=2;
}else if(cmaze[x+1][y]==0){
p=(stack *)malloc(sizeof(stack));
p->x=x+1;
p->y=y;
p->direction=1;
q=top->next;
top->next=p;
p->next=q;
cmaze[x+1][y]=2;
}else if(cmaze[x][y-1]==0){
p=(stack *)malloc(sizeof(stack));
p->x=x;
p->y=y-1;
p->direction=2;
q=top->next;
top->next=p;
p->next=q;
cmaze[x][y-1]=2;
}else if(cmaze[x+1][y]==0){
p=(stack *)malloc(sizeof(stack));
p->x=x;
p->y=y-1;
p->direction=3;
q=top->next;
top->next=p;
p->next=q;
cmaze[x+1][y]=2;
}else{
t=top->next;
s=t->next;
top->next=s;
free(t);
}
q=top->next;
x=q->x;
y=q->y;
//每次都是栈顶的元素找方向,找不到就是free掉,出栈,就是后退一步
}
for(i=0;i<10;i++){
for(j=0;j<10;j++){
printf(" %d",cmaze[i][j]);
}
printf("\n");
}
printf("溯源:\n");
while(top->next!=NULL){
p=top->next;
x=p->x;
y=p->y;
printf("x=%d,y=%d\n",x,y);
top=top->next;
}
return 0;
}

//队列
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define maxsize 10
#define null 0
typedef struct node{
int x;
int y;
struct node*last;
struct node*next;
} lqnode;
typedef struct{
node *front,*rear;
}Queue;
//定义一个队列的结构体,记录头和尾
int main(){
int maze[10][10];
int i,j;
for(i=0;i<10;i++){
for(j=0;j<10;j++){
if(i==0 || j==0 || i==9|| j==9){
maze[i][j]=1;
} else{
maze[i][j]=0;
}
}
}
maze[1][3]=1;
maze[1][7]=1;
maze[2][3]=1;
maze[2][7]=1;
maze[3][5]=1;
maze[3][6]=1;
maze[4][2]=1;
maze[4][3]=1;
maze[4][4]=1;
maze[5][4]=1;
maze[6][2]=1;
maze[6][6]=1;
maze[7][2]=1;
maze[7][3]=1;
maze[7][4]=1;
maze[7][6]=1;
maze[7][7]=1;
maze[8][1]=1;
for(i=0;i<10;i++){
for(j=0;j<10;j++){
printf(" %d",maze[i][j]);
}
printf("\n");
}
Queue *q;
lqnode *p;
q=(Queue *)malloc(sizeof(Queue));
p=(lqnode *)malloc(sizeof(lqnode));
p->next=null;
q->rear=p;
q->front=p;
int x,y;
lqnode *r,*t;
r=(lqnode *)malloc(sizeof(lqnode));
r->x=1;
r->y=1;
r->last=null;
q->rear->next=r;
r->next=null;
q->rear=r;
t=q->front->next;
x=t->x;
y=t->y;
printf("可以走的点\n");
while(x!=8 || y!=8){
if(maze[x][y+1]==0){
r=(lqnode *)malloc(sizeof(lqnode));
r->x=x;
r->y=y+1;
r->last=t;
q->rear->next=r;
r->next=null;
q->rear=r;
maze[x][y+1]=2;
}
if(maze[x+1][y]==0){
r=(lqnode *)malloc(sizeof(lqnode));
r->x=x+1;
r->y=y;
r->last=t;
q->rear->next=r;
r->next=null;
q->rear=r;
maze[x+1][y]=2;
}
if(maze[x][y-1]==0){
r=(lqnode *)malloc(sizeof(lqnode));
r->x=x;
r->y=y-1;
r->last=t;
q->rear->next=r;
r->next=null;
q->rear=r;
maze[x][y-1]=2;
}
if(maze[x+1][y]==0){
r=(lqnode *)malloc(sizeof(lqnode));
r->x=x+1;
r->y=y;
r->last=t;
q->rear->next=r;
r->next=null;
q->rear=r;
maze[x+1][y]=2;
}
//可以走的就加入队列,然后队列是从头开始循环的,一边循环一边加入了新元素
t=t->next;
x=t->x;
y=t->y;
printf("%d,%d\n",x,y);
}
printf("溯源:\n");
while(t->last!=NULL){
printf("x=%d,y=%d\n",t->x,t->y);
t=t->last;
}
//用last记录每一个节点是由哪个节点走过来的
return 0;
}

1 1 1 1 是上面的迷宫,截图没有截好
C语言之走迷宫深度和广度优先(利用堆栈和队列)的更多相关文章
- C语言动态走迷宫
曾经用C语言做过的动态走迷宫程序,先分享代码如下: 代码如下: //头文件 #include<stdio.h> #include<windows.h>//Sleep(500)函 ...
- golang 实现广度优先算法(走迷宫)
maze.go package main import ( "fmt" "os" ) /** * 广度优先算法 */ /** * 从文件中读取数据 */ fun ...
- golang广度优先算法-走迷宫
广度优先遍历,走迷宫思路: 1.创建二维数组,0表示是路,1表示是墙:创建队列Q,存储可遍历的点,Q的第一个元素为起始点 2.从队列中取一个点,开始,按上.左.下.右的顺序遍历周围的点next,nex ...
- 数据结构之 栈与队列--- 走迷宫(深度搜索dfs)
走迷宫 Time Limit: 1000MS Memory limit: 65536K 题目描述 一个由n * m 个格子组成的迷宫,起点是(1, 1), 终点是(n, m),每次可以向上下左右四个方 ...
- LeetCode 79,这道走迷宫问题为什么不能用宽搜呢?
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第48篇文章,我们一起来看看LeetCode当中的第79题,搜索单词(Word Search). 这一题官方给的难 ...
- sdut 2449走迷宫【最简单的dfs应用】
走迷宫 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_ 题目描述 一个由n * m 个格子组成的迷宫,起点是(1, 1), 终点是(n, m) ...
- 洛谷P1238 走迷宫
洛谷1238 走迷宫 题目描述 有一个m*n格的迷宫(表示有m行.n列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,文件读入这m*n个数据和起始点.结束点(起始点和结束点都是用两个 ...
- BZOJ 2707: [SDOI2012]走迷宫( tarjan + 高斯消元 )
数据范围太大不能直接高斯消元, tarjan缩点然后按拓扑逆序对每个强连通分量高斯消元就可以了. E(u) = 1 + Σ E(v) / degree(u) 对拍时发现网上2个程序的INF判断和我不一 ...
- NYOJ306 走迷宫(dfs+二分搜索)
题目描写叙述 http://acm.nyist.net/JudgeOnline/problem.php?pid=306 Dr.Kong设计的机器人卡多非常爱玩.它经常偷偷跑出实验室,在某个游乐场玩之不 ...
随机推荐
- npm中的安装环境依赖 -D,-S等等
什么都不写:这样不会写入到package.json中,直接安装到node_modules中,不建议这样写 -g:全局安装 -D:开发依赖,适合我们在开发阶段使用的依赖,包名会被注册到package.j ...
- 八个解决你80%需求的CSS动画库
八个解决你80%需求的CSS动画库 点击打开视频讲解 在学习和工作的过程中,我们总免不了要写各种各样的css动画,给某个部分添加动画效果,如果觉得自己写的动画效果单一乏味,不妨试试这8个CSS动画库, ...
- Host long.com not found: 2(SERVFAIL)
环境: centos 7.9 地址:192.168.200.100 相关配置 name.conf文件: named.zones文件: 正反解析文件: 重启DNS服务: 1 [root@server ...
- gorm tips
约定的列名 type User struct { ID uint // 列名是 `id` Name string // 列名是 `name` Birthday time.Time // 列名是 `bi ...
- 关于virtio_net网卡命名的小问题
最近看了一个小问题,涉及到一致性网络设备命名(Consistent Network Device Naming),在此记录一下. 系统是 4.18.0-240.el8.x86_64,centos 8. ...
- 【Java】学习路径46-两种创建多线程的方法、以及在匿名内部类创建线程
两种方法: 1.创建一个继承自Thread的线程类,然后再main(不限)中构造这个线程类对象.方法在之前讲过. 2.创建一个使用Runnable接口的线程类,然后在main(不限)中构造这个Runn ...
- 常用的SSH,你了解多少?(长文警告)
1.SSH工作原理 从ssh的加密方式说开去,看下文 1.1.对称加密 客户端和服务端采用相同的密钥进行数据的加解密,很难保证密钥不丢失,或者被截获.隐藏着中间人攻击的风险 如果攻击者插在用户与远程主 ...
- 第五十五篇:Axios的封装
好家伙, 上图 1.为什么需要封装axios? 当我们改变项目的使用环境时候,url也会随之改变,那么我们就需要改很多axios请求中的url配置 现在我们将axios封装,在项目使用环境改变时我们只 ...
- Docker容器网络基础总结
ifconfig 之 docker0 基于Linux的虚拟网桥(通用网络设备的抽象) 虚拟网桥特点: 1. 可以设置IP地址 2.相当于拥有一个隐藏的虚拟网卡 docker0 的地址划分 IP: 17 ...
- WebDriver常见操作
本文当个记录贴,记录WebDriver常用的一些函数(含自己封装的函数) 让WebDriver使用浏览器用户设置 1 option = webdriver.ChromeOptions() 2 opti ...