數據結構(9)隊列之鏈隊列
前言
隊列同棧一樣,本質都是操作受限的線性表。與棧不同的是,隊列只允許在一端進行插入操作,在另一端進行刪除操作,允許插入的一端稱爲隊尾,允許刪除的一端稱爲隊頭。從線性表的角度來看,也就是說隊列只支持頭部刪除和尾部插入操作。它的特性就是先進先出,同生活中的排隊現象類似。
鏈隊列的初始化
只要認識到隊列的本質是線性表,那麼隊列的鏈式存儲和線性表的鏈式存儲都是一致的,都需要考慮頭結點的問題。如果設置了頭結點,那麼在初始化鏈隊列時就需要生成一個頭結點併爲它賦初值;如果不設頭結點則直接將隊列賦空即可。爲了方便操作,此處是設了頭結點的。
其他操作同單鏈表基本一致,就不寫了
源代碼
LinkQueue.h
#ifndef LinkQueue_h
#define LinkQueue_h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define ElemType int
typedef struct QueueNode{
ElemType data;
struct QueueNode *next;
}QueueNode;
typedef struct LinkQueue{
QueueNode *fount;
QueueNode *tail;
}LinkQueue;
//初始化
void InitQueue(LinkQueue *Q);
//入隊
void EnQueue(LinkQueue *Q,ElemType x);
//出隊
void DeQueue(LinkQueue *Q);
//展示
void ShowQueue(LinkQueue *Q);
//獲取隊首元素
void GetHead(LinkQueue *Q,ElemType *x);
//獲取隊列長度
void GetLength(LinkQueue *Q);
//清除
void ClearQueue(LinkQueue *Q);
//摧毀
void DestoryQueue(LinkQueue *Q);
#endif /* LinkQueue_h */
LinkQueue.c
#include "LinkQueue.h"
//初始化
void InitQueue(LinkQueue *Q){
//申請頭結點的空間
QueueNode *s = (QueueNode *)malloc(sizeof(QueueNode));
assert(s != NULL);
//初始化值
Q->fount = Q->tail = s;
Q->tail->next = NULL;
}
//入隊->實際上就是尾部插入
void EnQueue(LinkQueue *Q,ElemType x){
//申請新結點的空間並賦值
QueueNode *s = (QueueNode *)malloc(sizeof(QueueNode));
assert(s != NULL);
s->data = x;
s->next = NULL;
//添加到隊列尾部
Q->tail->next = s;
//重新設置隊尾指針
Q->tail = s;
}
//出隊->實際上就是頭部刪除
void DeQueue(LinkQueue *Q){
//取出首元結點
QueueNode *s = Q->fount->next;
//判斷是否已空
if (s != NULL) {
Q->fount->next = s->next;
free(s);
}
//判斷刪除的是否是最後一個結點
if (Q->fount->next == NULL) {
Q->tail = Q->fount;
Q->tail->next = NULL;
}
}
//展示
void ShowQueue(LinkQueue *Q){
QueueNode *s = Q->fount->next;
while (s != NULL) {
printf("%4d",s->data);
s = s->next;
}
printf("\n");
}
//獲取隊首元素
void GetHead(LinkQueue *Q,ElemType *x){
if (Q->fount == Q->tail) {
//隊列爲空,無法獲取
printf("隊列已空\n");
return;
}
QueueNode *s = Q->fount->next;
*x = s->data;
}
//獲取隊列長度
void GetLength(LinkQueue *Q){
int length = 0;
QueueNode *s = Q->fount->next;
while (s != NULL) {
length ++;
s = s->next;
}
printf("長度爲:%d\n",length);
}
//清除
void ClearQueue(LinkQueue *Q){
QueueNode *s = Q->fount->next;
while (s != NULL) {
Q->fount->next = s->next;
free(s);
s = Q->fount->next;
}
Q->tail = Q->fount;
Q->tail->next = NULL;
}
//摧毀
void DestoryQueue(LinkQueue *Q){
ClearQueue(Q);
free(Q->fount);
Q->fount = Q->tail = NULL;
}
Main.c
#include "LinkQueue.h"
int main(int argc, const char * argv[]) {
LinkQueue Q;
InitQueue(&Q);
//入隊
for (int i = 0; i < 5; i ++) {
EnQueue(&Q, i);
}
//展示
ShowQueue(&Q);
//出隊
DeQueue(&Q);
ShowQueue(&Q);
//求長度
GetLength(&Q);
//清除
ClearQueue(&Q);
GetLength(&Q);
return 0;
}