数据结构实验四 栈和队列的综合应用

一、实验目的

1.深入了解队列的特点,以便在实际问题中灵活运用队列。

2.巩固对队列构造方法的理解。

3.熟练掌握循环队列、单向链式队列基本操作的C语言实现。

4.了解队列在实际问题中的应用,具备利用队列解决实际问题的能力。

5.具备总和利用栈和队列解决实际问题的能力。

二、实验题目

1.迷宫问题。假设迷宫由m行n列构成,有一个入口和一个出口,入口坐标为(1,1),出口坐标为(m,n),试设计并验证以下算法:找出一条从入口通往出口的路径,或报告一个“无法通过”的信息。

三、程序清单

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#define N 1000

int m,n,top=0;
int dx[]={-1,-1,0,1,1,1,0,-1},dy[]={0,1,1,1,0,-1,-1,-1};
char MAZE[N][N], mark[N][N];

typedef struct pos{
	int x;    //存放当前行位置 
	int y;    //存放当前列位置 
	int pre;  //当前位置的上一个位置 
}; 

typedef struct que{
	int head=0;
	int tail=-1;
	pos list[N*N];    //队列长度 
}queue;

typedef struct Stack{
	int i,j;      //用于存储可解迷宫的行走路径
}; 

queue t;
Stack s[N*N];

//此函数将可以走到的路径放入队列中 
void push(queue& t,int i,int j){   //i,j为当前坐标 
	t.list[++t.tail].x=i;
	t.list[t.tail].y=j;      //将行、列坐标存入
	if(t.head!=0){
		t.list[t.tail].pre=t.head;    //如果为第一个点,就不记录走到该点的上一个点
	} 
}

void push_stack(Stack* s,int i,int j){       //将有解路径放入栈中 
	s[++top].i=i;
	s[top].j=j;
} 

int find(){
	int flag=0;
	while(t.head<=t.tail){     //如果无解则head一定大于tail 
		int a=t.head;
		if(t.list[a].x==n-2&&t.list[a].y==m-2){    //如果当前位置为出口返回flag=1 
			flag=1;
			return flag;
		}
		for(int i=0;i<8;i++){
			int x=t.list[a].x+dx[i], y=t.list[a].y+dy[i];    //查找包围此位置的八个点 
			if(MAZE[x][y]=='0'&&mark[x][y]=='0'){           //如果下一个位置可走且为未走过的点,则将此点入队且标记为1 
				push(t,x,y);
				mark[x][y]='1';
			}
		} 
		++t.head; 
	}
	return flag;
}

int main(){
	int i,j;
	srand(time(NULL));   //让产生的随机数随机化 
	printf("请输入迷宫的行数:");
	scanf("%d",&m);
	printf("请输入迷宫的列数:");
	scanf("%d",&n);
	memset(mark, '0', sizeof(mark));// 将标记设为0,表示没有走过该点
	m=m+2;
	n=n+2;
	for(i=0;i<m;i++){      //动态数组的建立并填充并保证最外层为不准通过的墙(均为1) 
		for(j=0;j<n;j++){
			if(i==0||i==m-1||j==0||j==n-1)
				MAZE[i][j]='1';
			else
				MAZE[i][j]=rand()%2+'0';
		}
	}
	MAZE[1][1]='0';
	MAZE[m-2][n-2]='0';
	for(i=0;i<m+2;i++){
		for(j=0;j<n+2;j++){
			printf("%c ",MAZE[i][j]);
		}
		printf("\n"); 
	}
	push(t,1,1);
	int flag=find();
	if(flag==0)
		printf("No Path!!!");
	if(flag==1){
		int p=t.head;       // p表示终点在队列中的位置
		int i=t.list[p].x,j=t.list[p].y;   // i与j表示终点的行列
		push_stack(s,i,j);
		while(i!=1&&j!=1){
			p=t.list[p].pre;      // 将point变为当前点的上一个点
			i=t.list[p].x;
			j=t.list[p].y; 
			push_stack(s,i,j);    // 将当前点的上一个点行列坐标放入栈
		}
		printf("迷宫可走路径为:");
		for(int i=top;i>0;i--){
			printf("(%d,%d)",s[i].i,s[i].j);
		} 
	} 
	return 0;
}

四、实验结果 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值