Table of Contents
定義
在棧中提到,隊列是操作受限制的特殊的線性表。
在隊列的一端只能插入元素,這一端叫做隊尾。
在隊列的另一端只能刪除元素,這一端叫做隊首。
舉個栗子,在食堂排隊打飯,跑的快的同學排在隊列的前面,最先打到飯菜。後續到的同學只能依次排列在隊尾。買到飯菜的同學離開隊列叫做出隊,進入隊列等候叫做入隊。食堂阿姨給隊列中第一個同學打飯叫做訪問隊首元素。
總結:隊列有先進先出的特性,FIFO(First In First Out)。每次只能在線性表的兩端操作元素。
實現
考慮到每次出隊和入隊都要移動隊首和隊尾指針。若採用順序存儲,將會有可能造成順序表前段部分存儲單元的浪費。雖說可以採用循環隊列的方式複用存儲單元,若遇到隊列滿的情況,將隊列擴容比較麻煩。因此建議用鏈表的方式實現隊列。
定義結構
typedef int QueueType;
struct LinkQueue{
QueueType key;
struct LinkQueue *next;
};
typedef struct queueNode{
struct LinkQueue *head;//隊列的頭指針
struct LinkQueue *end;//隊列的尾指針
}Queue;
這裏定義了連個結構體,鏈表和隊列。隊列中只保存兩個指針——隊首、隊尾。後面的入隊、出隊的操作,只需要操作這兩個指針就好。
定義操作
創建隊列
/**
* 創建隊列
*/
Queue createQueue() {
Queue queue;
queue.head = 0;
queue.end = 0;
return queue;
}
採用靜態方式分配隊列存儲單元。初始化隊首和隊尾指針。
判斷隊列是否爲空
/**
* 判斷隊列是否是空
*/
int isEmpty(Queue queue) {
if (queue.head == 0)
return 0;
else
return 1;
}
隊首指針指向空結點,表示隊列爲空。
訪問隊首元素
/**
* 獲取隊列第一個元素
*/
int getFirst(Queue queue, QueueType& elem) {
if (queue.head == 0)
return 0;
elem = queue.head->key;
return 1;
}
隊首指針可作爲鏈表的頭結點。通過頭結點訪問鏈表的第一個結點。
出隊
/**
* 退出隊列
*/
int exitQueue(Queue& queue, QueueType& val) {
if (isEmpty(queue) == 0) //空隊列
return 0;
struct LinkQueue* node = queue.head;
queue.head = node->next;
node->next = 0;
val = node->key;
free(node);
if (queue.head == 0)
queue.end = 0;
return 1;
}
通過隊首指針,刪除隊列第一個結點。如果刪除後隊列爲空,將隊尾指針置空,否則隊尾指針仍然指向最後一個元素。隊列爲空,刪除失敗,返回0 。刪除成功返回1。
入隊
/**
* 進入隊列
*/
int enterQueue(Queue& queue, QueueType key) {
struct LinkQueue* node = (struct LinkQueue*) malloc(
sizeof(struct LinkQueue));
if (node == NULL)
return 0;
node->key = key;
node->next = 0;
if (queue.end == 0) {
queue.end = node;
} else {//修改隊尾指針
queue.end->next = node;
queue.end = node;
}
if (queue.head == 0) {
queue.head = node;
}
return 1;
}
隊列爲空時,隊首和隊尾指針指向同一個結點就好。隊列不爲空時,修改隊尾指針指向新插入的結點。入隊成功返回1,入隊失敗返回0。
最後附上頭文件的定義
/*
* queue.h
*
* Created on: 2016年9月30日
* Author: flueky
*/
#ifndef QUEUE_H_
#define QUEUE_H_
typedef int QueueType;
struct LinkQueue {
QueueType key;
struct LinkQueue *next;
};
typedef struct queueNode {
struct LinkQueue *head; //隊列的頭指針
struct LinkQueue *end; //隊列的尾指針
} Queue;
/**
* 創建隊列
*/
Queue createQueue();
/**
* 判斷隊列是否是空
*/
int isEmpty(Queue);
/**
* 獲取隊列第一個元素
*/
int getFirst(Queue, QueueType&);
/**
* 進入隊列
*/
int enterQueue(Queue&, QueueType);
/**
* 退出隊列
*/
int exitQueue(Queue&, QueueType&);
/**
* 清空隊列
*/
void clearQueue(Queue);
#endif /* QUEUE_H_ */