一.概述
队列是一种只允许咋一端进行操作(插入,删除)的线性表,与栈相比,栈是一种先进后出(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;
}
运行结果: