戳这里还有其他数据结构的题目噢

https://blog.csdn.net/qq_45724947/article/details/115625130?spm=1001.2014.3001.5501


题目:迷宫问题。假设迷宫由m行n列构成,有一个入口和一个出 口,大口坐标为(1, 1), 出口坐标为(m, n),试设计并验证以下算法:找出一-条从入口通往出口的路径,或报告一个“无法通过”的信息。
(1)用C语言实现顺序存储结构上队列的基本操作,然后利用该队列的基本操作找出迷宫的一条最短路径。
(2)设计一个二维数组MZEZEl+2)o+]表示迷宫,数组元素为0表示该位置 可以通过,数组元素为!表示该位置不可以通行。MAZEUID MAZEIm]分别为迷宫的入口和出口。
(3)输入建宫的大小m行和口列,动态生成二维数组:由随机数产生0或1.建立遗言。注意m*n中的迷宫需要进行扩展,扩展部分的元素设置为1.相当于在迷宫周围布上一圈不准通过的墙。
(4)要求输出模拟迷宫的二维数组:若存在最短路经,则由出口回溯到入口(出队列并利用栈实现),再打印从入口到出口的这条路径,例如(1,1),.....(j),.... (m)若没有路径,则打印-No pubr.
(5)迷宫的任何位置(i,j)上均有八个可以移动的方向,用二维数组Diretion存放八个方向上的位置偏移量。
Direction[8][2] ={ {-1,1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}}
(6)为避免出现原地踏步步的情况为了标志已经通过的位置,采用一个标志数组MARK[m+2][n+2],初值均为0,在寻找路径的过程中,若通过了位置(i,j),则将MARK[i][]置为1.
(7)为了记录查找过程中到达位置(i,j)及首次到达(ij)的前一位置
(i prej pre), 需要记住前一位置(i pre,j_ pre)在队列中的序号 pre,即队列中数据
元素应该是一个三元组(j,pre)。
(8)搜索过程简单描述如下:将入口MAZE[1][1]作为第一个出发点, 依次在
八个方向上搜索可通行的位置,将可通行位置(ij,pre)入队,形成第一层新的出发
点,然后依次出队,即对第一层中各个位置分别搜索它所在八个方向上的可通行
位置,形成第二层新的出发点,..如此进行下去,直至达到出口MAZE[m][n]
或者迷宫所有位置都搜索完毕为止。

 直接上代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

//创建基本迷宫三元组 
typedef struct Data{
	int row;//行 
	int col;//列 
	int previous;//前一个可通过的位置(开始探索方向的位置) 
}sData,qData;

int** createPuzzle(int row,int col){  // 实现 动态数组创建矩阵 函数 
	int **Puzzle;
	Puzzle = (int **)malloc(sizeof(int *) * row);//分配指针数组
	for(int i=0; i<row; i++)
	{
		Puzzle[i] = (int *)malloc(sizeof(int) * col);//分配每个指针所指向的数组
	}
	return Puzzle;
}

#define STACK_INIT_SIZE 1000  // 存储空间初始分配量
#define STACKINCREMENT 10  // 存储空间分配增量
#define true 1
#define false 0
#define OK 1
#define OVERFLOW -1

typedef int ElemType;
typedef int Status; //函数返回类型,其值为结果状态码

struct stack1{
	sData base[STACK_INIT_SIZE];
	int top;  //指示栈顶位置
};
typedef struct stack1 SqStack;

Status Push(SqStack *s,sData data){      //  元素入栈
	if(s->top==STACK_INIT_SIZE-1)
		return OVERFLOW;
	else{
	s->top++;
	s->base[(s->top)]=data;
	}
	return OK;
}

Status Pop(SqStack *s,sData *data){      //  栈顶元素出栈
	if(s->top==-1)
		return OVERFLOW;
	else{
		*data=s->base[s->top];
		s->top--;
	}	
	return OK;
}

Status Get(SqStack *s,sData *data){   // 得到栈顶元素
	if(s->top==-1)
		return OVERFLOW;
	else{
		*data=s->base[s->top];
		}
	return OK;
}

Status InitStack(SqStack *s){    //    初始化栈
	s->top=-1;
	if(!s->base)
		return OVERFLOW;
	return OK;
}

Status StackTraverse(SqStack *s){         //栈元素的遍历
	if(s->top==-1){
		printf("栈已空!\n");
		return OK;
	}
	while(s->top!=-1){
		printf("(%d,%d) ",s->base[s->top].row,s->base[s->top].col);  // 输出坐标
		s->top--;
	}
	printf("\n");
	return OK;
}

Status searchStackData(SqStack *s,sData data){//搜索当前位置 
	while(s->top>=0){
		if((s->base[s->top].row == data.row)&&(s->base[s->top].col == data.col))
			return true;
		s->top--;
	}
	return false;
}

#define ERROR 0   
#define OK 1
#define OVERFLOW -1
#define true 1
#define false 0
#define STACK_INIT_SIZE 1000

typedef int Status;   

typedef struct QUeue1{
	qData base[STACK_INIT_SIZE];    
	int front;  // 队头
	int rear;  // 队尾
}QNode;

Status InitQueue(QNode *Q){  // 初始化队列
	Q->front=0;  
	Q->rear=0;
	if(!Q->base)
		return OVERFLOW;
	return OK;
}

Status EnQueue(QNode *Q,qData data){  // 入队列
	if(Q->rear==STACK_INIT_SIZE-1)
		return OVERFLOW;
	else{
		Q->base[(Q->rear)]=data;
		Q->rear++;  //指向下一个元素
	}
	return OK;
}

Status DeQueue(QNode *Q,qData *data){  // 出队列,队列不为空,返回其值
	if(Q->front==Q->rear)
		return OVERFLOW;
	else{
		*data = Q->base[Q->front];
	}
	return OK;
}

Status rand(ElemType **p,int row,int col){ // 随机产生迷宫
	srand(unsigned(time(NULL)));
	int r,c;
	for(r = 0;r<row;r++)  
		for(c = 0;c < col;c++){
			if(r==0||c==0||r==row-1||c==col-1){   // 数组的第一行最后一行第一列最后一列均为墙
				p[r][c]=1;
			}
			else{
				p[r][c] = rand()%100;
				if(p[r][c]>=30)
					p[r][c]=0;    // 0 表示课通过 
				else
					p[r][c]=1;// 出现墙 
			}
		}
	p[1][1]=0;  //起点
	p[row-2][col-2]=0;  // 终点
	return OK;
}

int num = 1;

Status printPuzzle(int **m,SqStack *s, int row, int col){  // 打印迷宫
	sData *data,data1;
	int k = s->top;    // 记录栈元素的总个数
	int num1=0;
	int flag=1;
	data = &data1;
	for(int i=0;i<row;i++){
		for(int j=0;j<col;j++){
			if(i==0||j==0||i==row-1||j==col-1||m[i][j]==1){   //  输出迷宫墙
				printf("■");}
			else{
				data->row=i;
				data->col=j;
				if(searchStackData(s,data1)&&flag==1){	//输出当前位置 		
					printf("※");
					num1++;
					if(num1 == num)
						flag=0;
				}
				else{
					printf("  ");
				}
					s->top=k;
			}
			}
		printf("\n");  
	}
	return OK;
}

//迷宫寻找路径
int search_path(int **m,int **mark,QNode *Q,int row,int col,int d[][2]){
	int flag = 0;//判断是否可以走出迷宫 
	sData *data,data1,data2;//data2为将要探索时的坐标点
							//data1为探索点
	data=&data1;
	data->col = 1;
	data->row = 1;
	data->previous = -1;
	EnQueue(Q,data1);
	while(Q->front != Q->rear){   // 队列非空 
		int i,j;
		DeQueue(Q,data);
		i = data->row;  //将行 列赋给i j 便于加上方向判断是否有路径
		j = data->col;
		mark[i][j] = true;  // 示已经走过
		data2 = data1;
		data2.previous = Q->front;   // 记录上个开始探索方向的初始位置
		if((i==row-2)&&(j==col-2))   // 走出迷宫
		{ 	flag=1;
		 	break;}
		for(int k=0;k<8;k++){   // 搜索八个方向
			i=data->row;
			j=data->col;
			i+=d[k][0];
			j+=d[k][1];
			if(m[i][j]==1 || mark[i][j]==true)   // 遇见路障或者已在队列里
				continue;
			else{
				data2.row=i;
				data2.col=j;
				mark[i][j]=true;
				EnQueue(Q,data2); // 找到通路,入队
			}
		} 
		Q->front++;
	}  //while
	return flag;	 
}

Status PushData(QNode *q,SqStack *s){   //  将通过的路径放进栈
	sData data1;
	int i;
	i=q->front;  // 上一个元素的位置
	while(i!=-1){    // 起点的值为 -1
		data1=q->base[i];
		Push(s,data1);  // 坐标入栈
		i=q->base[i].previous;
	}
	return OK;
}
int showPuzzle(ElemType **m, int row, int col){
	sData *data,data1;
	data=&data1;
	for(int i=0;i<row;i++){
		for(int j=0;j<col;j++){
			if(i==0||j==0||i==row-1||j==col-1||m[i][j]==1)    //  输出迷宫墙
				printf("■");
			else
				printf("  ");
		}
		printf("\n");  
	}
	return OK;
}

int main(){
	int row,col;  //  随机产生迷宫的大小
	int flag;  // 判断是否走出了迷宫
	int k;
	int Directrion[8][2]={{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1},{0,1}};   // 右下角逆时针方向寻找路径
	ElemType **m=NULL,**mark=NULL;
	SqStack *s,s1;
	QNode *Q,q;
	Q = &q;
	s = &s1;
	InitQueue(Q); // 初始化 ======
	InitStack(s);
	printf("请输入迷宫的大小!\n");
	scanf("%d%d",&row,&col);
	row=row+2;col=col+2;  // 迷宫外部需要加上墙,所以数组大小加2(上下,左右)
	m=createPuzzle(row,col);  // 动态产生迷宫 m 
	mark=createPuzzle(row,col);   // 标记走过的位置
	for(int i=0;i<row;i++)
		for(int j=0;j<col;j++)
			mark[i][j]=false;   //  false 表示没有走过的位置
	rand(m,row,col);  // 随机产生迷宫障碍物
	flag=search_path(m,mark,Q,row,col,Directrion);  // 寻找路径
	if(flag==1){    // 可以走出迷宫
		PushData(Q,s);
		k=s->top;
		for(int i=0;i<k+1;i++){
			system("cls");
			printPuzzle(m,s,row,col);  // 打印迷宫
			num++;
			Sleep(500);
		}
		StackTraverse(s);   // 输出坐标
	}
	else
	{
		showPuzzle(m,row,col);
		printf("No Path!\n");
	}
return 0;
}

 (请不要直接复制使用。代码仅供参考,希望读者借此代码自身可以理解学习)

如果代码对您有帮助,不要忘记评论收藏噢~

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐