迷宮系列(一)棧、隊列、迷宮的表示和文件操作

一、棧

棧(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函數的參數列表相同

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章