C语言实现数据结构迷宫实验

本文实例为大家分享了C语言实现简单的数据结构迷宫实验,供大家参考,具体内容如下

分析:迷宫实验主要有两部分操作,其一是对迷宫的生成,其二是寻路使用栈的操作。

步骤:

一、.h文件

1、首先是迷宫的生成,可以使用随机数种子生成,但主要逻辑部分并不在此,所以在这里直接写死,固定下来。
定义一个坐标类型的结构体,和二维数组迷宫:

typedef struct {
 int x;
 int y;
}Pos;

//迷宫类型
typedef struct {
 int square[10][10] =
 {
{1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,1},
{1,1,1,1,0,1,1,1,0,1},
{1,0,0,0,0,1,0,1,0,1},
{1,0,1,1,1,1,0,1,1,1},
{1,0,0,0,0,1,0,0,0,1},
{1,0,1,1,0,0,0,1,0,1},
{1,0,1,1,1,0,1,1,1,1},
{1,0,0,0,1,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1},
 };
}Maze;
typedef Pos SElemType;

2、然后是对栈的声明,栈里储存的元素为坐标类型

//顺序栈
#define MAXSIZE 50
typedef struct {
 SElemType *base;
 SElemType *top;  //栈顶指针
 int stacksize;
}SqStack;

3、栈操作函数声明

typedef int Status;
#define OK 1;
#define ERROR 0;

//栈的相关操作
//初始化栈
Status initStack(SqStack &s);
//压栈
Status push(SqStack &s, SElemType e);
//出栈
SElemType pop(SqStack &s);
//清空栈
Status clearStack(SqStack &s);
//摧毁栈
void destroyStack(SqStack &s);
//遍历栈
Status stackTravel(SqStack s);

4、迷宫操作函数声明

//初始化迷宫(同时生成起始点和终点)
void initMaze(Maze &maze);
//打印迷宫
void showMaze(Maze maze);
//寻找出路;传入一个迷宫和栈找出出路
void findWay(Maze &maze,SqStack &s);
//判断该点的四个方向是否有通路,有就前进
Pos isExit(Pos p, Maze maze);

二、.cpp文件

1、导入所需头文件

#include "pch.h"
#include <iostream>
#include<time.h>
#include<stdlib.h>
using namespace std;

2、栈操作实现

//构造空栈
Status initStack(SqStack &s) {
 s.base = new SElemType[MAXSIZE];
 if (!s.base)
 {
 exit(OVERFLOW);//分配失败
 }
 s.top = s.base;
 s.stacksize = MAXSIZE;
 return OK;
}

//入栈
Status push(SqStack &s, SElemType e) {
 //判断栈满
 if (s.top-s.base == s.stacksize)
 {
 return ERROR;
 }
 //存入元素,*为取指针的值
 s.top++;
 *s.top = e;
 return OK;
}

//出栈,用e返回栈顶值
SElemType pop(SqStack &s) {
 SElemType e;
 //判断栈为空
 if (s.top == s.base)
 {
 //若为空则返回一个(-1,-1)的点,判断由外部调用时进行
 e.x = -1;
 e.y = -1;
 return e;
 }
 e = *s.top;
 s.top--;
 return e;
}

Status clearStack(SqStack &s) {
 s.top = s.base;
 return OK;
}

void destroyStack(SqStack &s) {
 s.top = NULL;
 s.stacksize = 0;
 free(s.base);
}

Status stackTravel(SqStack s) {
 while (s.top != s.base)
 {
 s.base++;
 Pos p = *s.base;
 //输出走过的路径
 cout <<"("<<p.x<<","<<p.y<<")"<< "-->";
 if ( p.x == 0 || p.y == 0|| p.x == 9 ||p.y == 9)
 {
 //终点输出为“End”
  cout << "End";
 }
 }
 cout << endl;
 return 0;
}

3、迷宫操作实现

///////////////////////////////////////迷宫操作////////////////////////////////
//初始化函数,传入一个迷宫,随机生成起点和终点,由于起点有一定限制,所以这里起点也固定为几个最合适的点
void initMaze(Maze &maze) {
 //生成随机数
 srand((unsigned)time(NULL));
 int index = rand() % 36 + 1;
 int start = index % 6 + 1;
 //生成起始点数值为‘s'
 switch (start)
 {
 case 1:
 maze.square[1][1] = 's';
 break;
 case 2:
 maze.square[3][8] = 's';
 break;
 case 3:
 maze.square[3][6] = 's';
 break;
 case 4:
 maze.square[6][8] = 's';
 break;
 case 5:
 maze.square[8][3] = 's';
 break;
 case 6:
 maze.square[8][8] = 's';
 break;
 }
 //随机生成终点'e'表示
 while (index = rand()%36+1)
 {
 //出口在顶部
 if (index >1 &&index<10 && maze.square[1][index-1]!='s')
 {
  maze.square[0][index-1] = 'e';
  break;
 }
 //出口在右侧
 else if (index>10 &&index <19)
 {
  if (maze.square[index-10][8] != 1 && maze.square[index-10][8]!='s') {
  maze.square[index-10][9] = 'e';
  break;
  }
 }
 //底部出口
 else if (index >19&&index<28)
 {
  if (maze.square[8][index - 19] != 's' && maze.square[8][index - 19] != 1) {
  maze.square[9][index - 19] = 'e';
  break;
  }
 }
 //左侧出口
 else if (index >28 && index <=36)
 {
  if (maze.square[index-28][1] != 1 &&maze.square[index-28][1] != 's')
  {
  maze.square[index - 28][0] = 'e';
  break;
  }
 }
 }
}

void showMaze(Maze maze) {
 for (int i = 0; i < 10; i++)
 {
 for (int j = 0; j < 10; j++)
 {
  if (maze.square[i][j] == 1)
  {
  cout << "* ";
  }
  else if (maze.square[i][j] == 0)
  {
  cout << " ";
  }
  else
  {
  cout << (char)maze.square[i][j]<<" ";
  }
 }
 cout << endl;
 }
}
//寻找迷宫路径
void findWay(Maze &maze,SqStack &s) {
//首先遍历找出起始点和终点并保存下来
 Pos start,end;
 for (int i = 0; i < 10; i++)
 {
 for (int j = 0; j < 10; j++) {
  if (maze.square[i][j] == 's')
  { //起点压入栈内
  start.x = i;
  start.y = j;
  push(s, start);
  }
  else if (maze.square[i][j] == 'e')
  { //出口
  end.x = i;
  end.y = j;
  }
 }
 }
 //寻找路径
 Pos go = start;
 //直到找到出口才结束
 while ( s.top->x != end.x || s.top->y != end.y)
 {
 //获得下一步坐标
 Pos path = isExit(go, maze);
 if (path.x != go.x || path.y != go.y)
 {
  //前进
  maze.square[path.x][path.y] = 'p';
  push(s, path);
  go = path;
 }
 //如果所有放向都走不通(即返回的点是传入的点),则将其标为“@”,出栈到上一个点,继续判断
 else
 {
  //走不通pop
  maze.square[path.x][path.y] = '@';
  pop(s);
  go = *s.top;
 }
 }
 maze.square[end.x][end.y] = 'e';
}

//判断返回下一步路径(顺序:右下左上),传入所处位置,从右边开始判断是否又通路或者出口,有就返回哪个方向上的点
Pos isExit(Pos p,Maze maze) {
 Pos tempP = p;
if (maze.square[tempP.x][tempP.y+1] == 0 || maze.square[tempP.x][tempP.y + 1] == 'e')
 {
 tempP.y++;
 }
 else if(maze.square[tempP.x+1][tempP.y] == 0 || maze.square[tempP.x +1][tempP.y] == 'e')
 {
 tempP.x++;
 }
 else if (maze.square[tempP.x][tempP.y - 1] == 0 || maze.square[tempP.x][tempP.y - 1] == 'e')
 {
 tempP.y--;
 }
 else if (maze.square[tempP.x - 1][tempP.y] == 0 || maze.square[tempP.x - 1][tempP.y] == 'e')
 {
 tempP.x--;
 }
 return tempP;
}

三、main函数调用

int main()
{
 while (true)
 {
 //创建一个迷宫
 Maze maze;
 initMaze(maze);
 //初始化一个栈
 SqStack S;
 initStack(S);
 cout << "*****************************" << endl;
 cout << "* 1、生成迷宫  2、退出 *" << endl;
 cout << "*****************************" << endl;
 cout << "请输入你的选择:";
 int select = 0;
 cin >> select;
 if (select == 1)
 {
  cout << "生成随机起点和出口迷宫:" << endl;
  showMaze(maze);
  cout << "生成迷宫路径:" << endl;
  findWay(maze, S);
  stackTravel(S);
  showMaze(maze);
  cout << endl;
 }
 if (select == 2)
 {
  clearStack(S);
  break;
 }
 }
 return 0;
}

四、评价

这是个叫简易的迷宫,但基本实现了迷宫的寻路逻辑,可改进的地方有:

1、因为很多地方写死了,所以复用性不高,可以用循环遍历来随机生成起点,同理迷宫的生成也是这样
2、判断路径可以用递归调用实现前进逻辑

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C语言数据结构之迷宫问题

    本文实例为大家分享了数据结构c语言版迷宫问题栈实现的具体代码,供大家参考,具体内容如下 程序主要参考自严蔚敏老师的数据结构c语言版,在书中程序的大体框架下进行了完善.关于迷宫问题的思路可查阅原书. #include<iostream> using namespace std; #define MAXSIZE 10 typedef int Status; typedef struct{ int x; int y; }Postype; typedef struct{ int ord; Postyp

  • C语言清除scanf()缓存的案例讲解

    又重新过一遍C语言,感觉每次重学C语言都有不同的感受,遇到了一个问题,就是scanf()这个问题,其实细究起来,也有很多可以值得深挖的,实际上每次细细的挖掘的话,都是对C语言的更透彻的认识. 那么下面我就对scanf()中清除输入缓冲区的方法讲解: 应用场景:我们使用多个scanf()的时候,如果输入缓冲区还有数据的话,那么scanf()就不会询问用户输入,而是直接就将输入缓冲区的内容拿出来用了,这就导致了前面的错误影响到后面的内容,为了隔离这种问题, 总的思想:通过各种方法将输入缓冲区的内容读

  • C语言实现小学生随机出题测试计分

    本文实例为大家分享了C语言实现随机出题测试计分的具体代码,供大家参考,具体内容如下 #include <stdio.h> #include <stdlib.h> #include <time.h> int test(); int checknum(int a, int b); int checkresult(int x); int a = -1, b, c, x; static int k = 0, grade; void main() { printf("请

  • C语言实现歌手大奖赛计分程序

    本文实例为大家分享了C语言实现歌手大奖赛计分程序的具体代码,供大家参考,具体内容如下 1. 题目描述 编写一个程序,用户输入评委人数和分数后,程序可以计算去掉一个最高分和最低分后的平均成绩.可多次输入选手成绩,输入N时退出程序. 2. 源代码 #include <stdio.h> #include <stdlib.h> float score[99];//成绩数据 int num=0;//评委数目 float sum=0;//总分 //输入打分数据并输出结果 void inputS

  • C语言实现小学生考试系统

    本文实例为大家分享了C语言实现小学生考试系统的具体代码,供大家参考,具体内容如下 问题及代码: /*烟台大学计算机学院 题目描述:做一个小学生考试系统,功能包括: (1)利用随机数出10道加法题: (2)小学生用户答题给出每道题的答案: (3)对小学生的答题进行评判: (4)计算出小学生答题正确率. 作者:景怡乐 完成时间:2016年12月29日 */ #include <stdio.h> #include <stdlib.h> #include <time.h> in

  • C语言数据结构之迷宫求解问题

    现在网上各种对于迷宫的求解,版本多的数不胜数.本人小白一枚,贴上自己对迷宫的求解这个小项目,自己写的.望能帮助一些同样有困难的人,毕竟我当时费解了好一会儿时间呢. 首先,先标明对于迷宫求解这个项目,首先我提出自己的思路,利用"穷举求解"的方法(严蔚敏老师数据结构一书中提到,一开始不知方法其名.)其实简单来说就是一条路一条路去试,当然不能随便试,我的方法是按照从入口出发,顺一个方向向前探索,走得通就继续向前走:否则留下标记沿原路退回并换一个方向继续探索,直到所有的路都走完为止.还是用栈的

  • C语言实现小型电子词典

    本文实例为大家分享了C语言实现小型词典系统,供大家参考,具体内容如下 1. 题目描述 用C语言编写一个小型词典,用户可以进行英译汉.汉译英.删除修改单词.添加单词等功能. 2.源代码 /* 小型词典系统 版本:0.9 作者:个快快 应用模型:文件增删改查 */ #include <stdio.h> #include <string.h> int worsNumber = 0; //单词数目 //---------------------- //定义结构体存储词典数据 //-----

  • C语言实现小学生计算机辅助教学系统

    开发一个小学生计算机辅助教学系统.使用随机书产生函数产生1~10之间的随机数作为操作数,随机产生一道四则运算题,配合使用switch语句和print()函数调用,来为学生输入的正确或者错误的答案输出不同的评价.若10道题做完之后正确率低于75%,则重新做10道题,直到回答正确率高于75%时才退出程序.要求用模块化程序设计方法来编程. #include<stdio.h> #include<stdlib.h> #include<time.h> int Calculate(i

  • C语言链表实现歌手评分系统

    本文实例为大家分享了C语言链表实现歌手评分系统的具体代码,供大家参考,具体内容如下 此程序可以添加文件操作用于保存歌手得分等信息,此程序实现了链表的增删查和链表冒泡排序交换节点功能 #include <stdio.h> #include <stdlib.h> #include <string.h> //创建结构体及其成员 typedef struct Node { int num;//编号 char name[20];//姓名 float grade[10];//评委评

  • C语言实现无规律数据加密、解密功能

    在网络传输重要信息或存储重要文件信息时,大部分会对数据加密,保证数据的安全性.互联网上流行的可逆加密方式对数据的安全性没有保证,便自己写了一套安全性极高加密.解密方法. 方法的实现方式及特点: 1.采用指定单个字节加密转换(转换形式为ascll码表中0-128的形式,由1个字节拆分为三个字节,下面说明拆分方式): 2.采用数组中随机数据减指定加密字节(比如当前数据ascll码为121,当前数组中的数据为222,结果为222-121=101,当然这个只是参考实例): 3.采用随机指定数组方式(如果

随机推荐