一.概述
隊列是一種只允許咋一端進行操作(插入,刪除)的線性表,與棧相比,棧是一種先進後出(Fast In Last Out)的形式,隊列則是先進先出(Fast In Fast Out),就像我們日常生活中的排隊一樣(大家都很有素質)。
二.結點定義
使用鏈式存儲結構的方式,結點的定義:
typedef struct QNode {
ElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct {
QueuePtr front,rear; //隊頭,隊尾指針
}LinkQueue;
爲了方便操作,通常,會添加一個不用來存儲數據的頭結點:
二. 初始化隊列
通過前面所說,創建一個隊列,可以先創建一個頭結點,再將我們定義好的頭指針與尾指針指向頭結點即可:
int InitQueue(LinkQueue *q)
{
q->front = q->rear = (QueuePtr)malloc(sizeof(QNode));
if(!q->front)
{
printf("Malloc failure\n");
return -1;
}
q->front->next = NULL;
}
三. 入列
聯想隊列的存儲結構,隊列是從隊尾插入,當有一個結點p想要進入隊列,則需要下面的幾個步驟:
代碼:
void InsetQueue(LinkQueue *q,ElemType e) //插入元素
{
QueuePtr p;
p = (QueuePtr)malloc(sizeof(QNode));
if(!p)
{
printf("Malloc failure\n");
exit(0);
}
p->data = e;
p->next = NULL;
q->rear->next = p;
q->rear = p;
}
四. 出列
獲取到第一個結點的值,將頭指針指向第二個結點:
需要注意兩點,一是要先判斷鏈表是否爲空,二是判斷出列一個元素後,鏈表是否爲空:
void DeleteQueue(LinkQueue *q,ElemType *e)
{
if(q->front == q->rear)
{
printf("鏈表當前爲空\n");
return;
}
QueuePtr p;
p = q->front->next;
*e = p->data;
q->front->next = p->next; //指向第二個結點
if(q->rear == p)
{
q->rear = q->front;
printf("隊列最後一個元素出列,隊列成爲空隊列\n");
}
free(p);
}
五. 銷燬隊列
如果隊列過長將會佔用極大一部風存儲空間,在使用完時需要及時銷燬從而釋放內存,首先,將rear指針指向front->next,銷燬front,再將front指向rear,rear再次指向front->next,直達最後都爲NULL則結束:
代碼:
void DestroyQueue(LinkQueue *q)
{
while(q->front)
{
q->rear = q->front->next;
free(q->front);
q->front = q->rear;
}
printf("鏈表已銷燬\n");
}
六. 運行程序
源碼:
/*********************************************************************************
* Copyright: (C) 2020 Xiao yang IoT System Studio
* All rights reserved.
*
* Filename: Queue.c
* Description: This file
*
* Version: 1.0.0(06/20/2020)
* Author: Lu Xiaoyang <[email protected]>
* ChangeLog: 1, Release initial version on "06/20/2020 09:06:49 AM"
*
********************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define ElemType int
typedef struct QNode {
ElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct {
QueuePtr front,rear; //隊頭,隊尾指針
}LinkQueue;
void InitQueue(LinkQueue *q)
{
q->front = q->rear = (QueuePtr)malloc(sizeof(QNode));
if(!q)
{
printf("Malloc failure\n");
exit(0);
}
q->front->next = NULL;
}
void InsertQueue(LinkQueue *q,ElemType e)
{
QueuePtr p;
p = (QueuePtr)malloc(sizeof(QNode));
if(!p)
{
printf("Malloc failure\n");
exit(0);
}
p->data = e;
p->next = NULL;
q->rear->next = p;
q->rear = p;
}
void DeleteQueue(LinkQueue *q,ElemType *e)
{
if(q->front == q->rear)
{
printf("鏈表當前爲空\n");
return;
}
QueuePtr p;
p = q->front->next;
*e = p->data;
q->front->next = p->next; //指向第二個結點
if(q->rear == p)
{
q->rear = q->front;
printf("隊列最後一個元素出列,隊列成爲空隊列\n");
}
free(p);
}
void DestroyQueue(LinkQueue *q)
{
while(q->front)
{
q->rear = q->front->next;
free(q->front);
q->front = q->rear;
}
printf("鏈表已銷燬\n");
}
int main(int argc, char *argv[])
{
int i = 0;
int temp;
LinkQueue Que;
InitQueue(&Que);
for(i = 1; i <=10; i++)
{
InsertQueue(&Que,i);
}
for(i = 1; i<= 10; i++)
{
DeleteQueue(&Que,&temp);
printf("獲取到鏈表元素%d \n",temp);
}
DestroyQueue(&Que);
return 0;
}
運行結果: