数据结构-图的搜索

一、实验目的

熟悉图的相关操作,掌握图的搜索算法及其应用,同时进一步练习栈与队列在实际问题中的应用。

二、问题描述

一只老鼠走进了一个迷宫,这个迷宫是由M行N列(如:10行8列)的方格构成的,相邻方格之间可能是相通的,也可能有墙相隔,各方格位置由其对应坐标确定,如图所示。迷宫在(1,1)处有一个入口,在(M,N)处有一个出口,在入口和出口之间有通路相通。问题是让你帮助老鼠找出从入口到出口的一条最短路径。

0 0 0 0 1 0 0 0

1 1 0 0 1 0 1 0

0 0 0 1 0 0 0 0

0 0 0 0 1 0 1 0

1 0 1 0 0 0 0 0

0 0 1 1 1 0 1 1

1 0 0 0 1 0 0 0

三、需求分析

迷宫用数组表示,1代表是墙走不通,0表示可以通行。边界可以扩充为墙,即M×N迷宫用(M+2)×(N+2)数组表示。目的是为老鼠找出从入口到出口一条最短路径。

采用图的广度优先搜索算法,新建空队列。最后运用递归从终点通过之前记录的父结点直到起始坐标并正向输出最短路径。

四、系统设计

坐标结构体:

struct poi

{

   int x;

   int y;

};

队列结构体:

struct qnode

{

   poi data[maxsize];

   int front;

   int rear;

};

图的存储结构体:

struct node

{

   int M;

   int N;

   int **G;

};

六个函数分别用于新建队列,队列数据插入,删除,新建图,广度遍历算法和递归输出最短路径。

首先新建队列和图结构,因为所有存储的最大值未知,所以都选择了定义头指针,在新建的时候动态存储数据。

将图进行广度遍历,标记已遍历坐标并存储坐标的上一个坐标。

最后从终点开始,通过寻找该坐标的上一个坐标进行遍历直到找到起始位置开始并倒序输出坐标。

五、调试分析

输入二维数组时,不能直接粘贴,需要有0隔开。

在图的遍历中需要注意溢出的问题和在对于图的存储定义的时候使用了0下标的位置所以在最后调试的时候修改了一些相关的判断语句。

六、代码实现

#include<stdio.h>
#include<stdlib.h>
#define maxsize 100
typedef struct qnode * Queue;
typedef struct node * Gragh;
struct poi **TreeFather;
int M,N;
struct poi
{
	int x;
	int y;
};
struct qnode
{
	poi data[maxsize];
	int front;
	int rear;
};
struct node
{
	int M;
	int N;
	int **G; 
};
 
Queue Createqueue()
{
	Queue Q=(Queue)malloc(sizeof(struct qnode));
	Q->front=Q->rear=0;
	return Q;
}
 
void Insertqueue(Queue Q,poi x)
{
	if((Q->rear+1)%maxsize==Q->front)
	printf("Full!");
	else
	{
		Q->data[Q->rear]=x;
		Q->rear=(Q->rear+1)%maxsize;
	}
}
 
void Deletequeue(Queue Q,poi* temp)
{
	if(Q->front==Q->rear)
		return;
	else
	{
		*temp=Q->data[Q->front];
		Q->front=(Q->front+1)%maxsize;
	}
}
 
Gragh Creategragh()
{
	int i,j,v,e,k;
	Gragh T=(Gragh)malloc(sizeof(struct node));
	printf("请输入M和N:");
	scanf("%d %d",&M,&N); //行数和列数 
	T->M=M;
	T->N=N;
	T->G=(int**)malloc(M*sizeof(int*));
	TreeFather=(struct poi**)malloc(M*sizeof(struct poi*));
	for(i=0;i<N;i++)
	{
		TreeFather[i]=(poi*)malloc(N*sizeof(poi));
		T->G[i]=(int*)malloc(N*sizeof(int)); 
	}
	for(i=0;i<M;i++)
	{
		for(j=0;j<N;j++)
		{
			scanf("%d",&k);
			T->G[i][j]=k;
		}
    }
	return T;
}
 
void bfs(Gragh g,poi X,Queue Q)
{
	int i,x,y;
	poi temp,test;
	Insertqueue(Q,X);
	g->G[0][0]=2;
	while(Q->front!=Q->rear)
	{
		Deletequeue(Q,&temp);
		x=temp.x;
		y=temp.y;
		if(x<M-1&&g->G[x+1][y]==0&&x>=0)
		{
			g->G[x+1][y]=2;
			test.x=x+1; test.y=y;
			Insertqueue(Q,test);
			TreeFather[x+1][y].x=x; TreeFather[x+1][y].y=y;
		}
		if(x>0&&g->G[x-1][y]==0&&x<=M-1)
		{
			g->G[x-1][y]=2;
			test.x=x-1; test.y=y;
			Insertqueue(Q,test);
			TreeFather[x-1][y].x=x; TreeFather[x-1][y].y=y;
		}
		if(y<N-1&&g->G[x][y+1]==0&&y>=0)
		{
			g->G[x][y+1]=2;
			test.x=x; test.y=y+1;
			Insertqueue(Q,test);
			TreeFather[x][y+1].x=x; TreeFather[x][y+1].y=y;
		}
		if(y>0&&g->G[x][y-1]==0&&y<=N-1)
		{
			g->G[x][y-1]=2;
			test.x=x; test.y=y-1;
			Insertqueue(Q,test);
			TreeFather[x][y-1].x=x; TreeFather[x][y-1].y=y;
		}
	}
}

void search(int i,int j)
{
	int x,y;
	x=TreeFather[i][j].x;//父结点 
	y=TreeFather[i][j].y;
	if(x>=0&&y>=0&&x+y>0)//出错点 
	{
		search(x,y);
	}
	printf("->(%d,%d)",i+1,j+1);
}
 
int main()
{
	int i,j;
	poi temp;
	temp.x=0; temp.y=0;
	Queue Q=Createqueue();
	Gragh gragh=Creategragh();
	bfs(gragh,temp,Q);
	printf("(1,1)");
	search(M-1,N-1);
	return 0;
}

七、实验结果测试

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值