迷宫系列(一)栈、队列、迷宫的表示和文件操作

来源:互联网 发布:爱因斯坦名言知乎 编辑:程序博客网 时间:2024/06/12 13:13

一、栈

栈(stack)又名堆栈,它是一种特殊的线性表。其限制是仅允许在表的一端进行插入(push)和删除(pop)运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
一个栈
由于堆叠数据结构只允许在一端进行操作,因而按照后进先出(LIFO, Last In First Out)的原理运作。
堆栈的实现一般有两种方式:链表和数组,在本程序中使用数组模拟栈结构。

二、队列

队列,又称为伫列(queue),是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为rear)进行插入(enQueue)操作,在前端(称为front)进行删除(deQueue)操作。
队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加。
队列
在本程序中使用数组模拟队列,队列的类型是循环队列。

※循环队列

1. 为什么使用循环队列

上溢
我们在程序中使用了数组来模拟队列,数组自身的限制就在于,如果不使用malloc、realloc这样的方法,数组的大小(队列的长度)必须在定义的时候明确指定,一旦队列已存数据的长度达到了数组的长度,即使队列头部已经进行了很多deQueue的操作,我们已经不能继续向队列中添加元素。为了充分利用数组的空间,我们使用循环队列。

2. 循环队列的形象解释:就像一个圈,小朋友手拉手站成一个圈

————————————————
循环队列
————————————————
参数解释:
front:指向队头元素的位置
rear:指向队尾元素的下一个位置(尾后)
maxsize:用数组实现的循环队列能容纳的最大元素数量 + 1,也就是说浪费了一个空间,主要用来判断队列状态
————————————————
队列的状态:
a. 一般情况:非空非满
b. 队列为空:front==rear
c. 队列满:front==(rear+1)% maxsize

3. 循环队列的使用

假设队列的maxsize为7
注意:以下示例中front与rear均代表所指向的下标的值
————————————————
1
初始化,front=rear=0
————————————————
2
入队:
enQueue(1),front=0,rear=(rear+1)%maxsize=1
————————————————
3
依次入队2,3,4,5,6,front=0,rear=6
注意:此时(rear+1)%maxsize=0 == front,说明队列已满,无法再插入下一个数据
————————————————
4
出队:
deQueue,返回front指向位置的元素(1),front=(front+1)%maxsize=1
————————————————
5
入队:
enQueue(7),front=1,rear=(rear+1)%maxsize=0
出队:
deQueue,返回front指向位置的元素(2),front=(front+1)%maxsize=2
————————————————
6
入队:
enQueue(8),front=2,rear=(rear+1)%maxsize=1
注意:此时(rear+1)%maxsize=2 == front,队列再次已满,无法插入
————————————————
7
出队:依次返回3,4,5,6 front=6,rear=1
————————————————
8
出队:deQueue,返回front指向位置的元素(7),front=(front+1)%maxsize=0
————————————————
9
出队:deQueue,返回front指向位置的元素(8),front=(front+1)%maxsize=1
注意:此时front == rear,队列为空,无法deQueue
————————————————

三、迷宫的表示

输入:
第一行有两个数字n m,表示迷宫的行数和列数
以下是一个n*m的矩阵,用来表示整个迷宫
输入样例:
maze_sample
1 : 墙壁
0 : 通路
S : 起点
E : 终点

#define START 1  //起始点#define END 2    //结束点#define WAY 3    //通路#define WALL 4   //墙壁

使用宏定义的好处:使用表情达意的人类语言终归是便于理解/使用的对吧= ̄ω ̄=

迷宫的保存

本程序使用结构体类型保存数组,
结构体定义:

1. 用于保存格点信息的结构体:

typedef struct _grid{  int dis;    //距离起始点的距离  int isVis;  //是否访问  int T;    //保存坐标信息(程序开头的#define)} grid;grid map[1000][1000];  //定义整个迷宫

2.用于保存点的结构体

typedef struct _point{  int x;  int y;} point;point start, end;  //保存起始结束点的信息

可还要说说使用结构体的好处:
1.简化变量定义
2.方便传参
3.使函数的返回值不限于一个玩意

四、补充知识

文件的操作

C语言提供多种文件操作函数,本程序使用fopen函数及FILE*文件指针

1.FILE*文件指针

使用方法:FILE *ptrname;//声明了一个文件指针,名为ptrname

2.fopen函数

使用方法:

文件指针=fopen(文件名,文件打开方式);新版VS这样要求:fopen_s(指向文件指针的指针,文件名,文件打开方式);

文件打开方式:(本程序中使用的)
“w” 新建一个文本文件,已存在的文件将被删除,只允许写
“a” 打开或新建一个文本文件,只允许在文件末尾追写
“r” 打开一个文本文件,文件必须存在,只允许读
示例:

FILE *in;in = fopen(“maze_in.txt”, “r”);

fopen_s(&in, “maze_in.txt”, “r”)

解释:定义了一个名为in的文件指针,它的操作是以只读模式打开maze_in.txt

3.如何进行文件操作

fscanf(ptrname, ......) //后面与scanf函数的参数列表相同

fprintf(ptrname, ......) //后面与printf函数的参数列表相同