目录
一、队列的概念
二、队列的实现
1、头文件定义
2、功能函数实现
3、主函数测试
一、队列的概念
队列就像吃饭排队类似,先来先吃,先进先出。
队头:队列的头部。
队尾:队列的尾部。
入队:在队尾操作。
出队:在队头操作。
二、队列的实现
因为出队列需要对队头操作,而数组对队头操作需要遍历,所以队列用链表实现更优。而单链表较双向链表占用空间更小,且同样能实现队列,所以用单链表更好。
队列的实现类似于单链表,所以定义了链表用的节点结构体,而队列需要对头和尾操作,所以再定义结构体分别表示队列的头和尾。头和尾分别指向链表的头部和尾部。
定义头和尾方便,为什么单链表实现不定义头和尾,因为在链表尾删的时候,需要改变尾节点的前一个节点的指针,而尾节点找不到尾节点的前一个结点,还是需要遍历链表,定义尾部意义不大。
1、头文件定义
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
typedef int QDataType;
//链式结构,表示队列
typedef struct QList
{
struct QList* next;
QDataType data;
}QList;
//队列的结构
typedef struct Queue
{
QList* front;
QList* rear;
int size;
}Queue;
//队列初始化
void QInit(Queue* ps);
//队尾入队列
void QPush(Queue* ps, QDataType x);
//队头出队列
void QPop(Queue* ps);
//获取队列队头元素
QDataType QFront(Queue* ps);
//获取队列队尾元素
QDataType QRear(Queue* ps);
//检测队列是否为空
bool QEmpty(Queue* ps);
//获取队列数据个数
int QSize(Queue* ps);
//销毁队列
void QDestory(Queue* ps);
2、功能函数实现
#include "Queue.h"
//队列初始化
void QInit(Queue* ps)
{
assert(ps);
ps->front = ps->rear = NULL;
ps->size = 0;
}
//申请空间
QList* QCheck(QDataType x)
{
QList* new = (QList*)malloc(sizeof(QList));
if (new == NULL)
{
perror("malloc fail\n");
exit(1);
}
new->data = x;
new->next = NULL;
return new;
}
//队尾入队列
void QPush(Queue* ps, QDataType x)
{
assert(ps);
QList* new = QCheck(x);
if (ps->front == NULL)
{
ps->front = ps->rear = new;
}
else
{
ps->rear->next = new;
ps->rear = new;
}
ps->size++;
}
//队头出队列
void QPop(Queue* ps)
{
assert(ps);
assert(ps->front);
QList* nextfront = ps->front->next;
free(ps->front);
ps->front = nextfront;
if (ps->front == NULL)
{
ps->rear = NULL;
}
ps->size--;
}
//获取队列队头元素
QDataType QFront(Queue* ps)
{
assert(ps);
assert(ps->size > 0);
return ps->front->data;
}
//获取队列队尾元素
QDataType QRear(Queue* ps)
{
assert(ps);
assert(ps->size > 0);
return ps->rear->data;
}
//检测队列是否为空
bool QEmpty(Queue* ps)
{
assert(ps);
return ps->size == 0;
}
//获取队列数据个数
int QSize(Queue* ps)
{
assert(ps);
return ps->size;
}
//销毁队列
void QDestory(Queue* ps)
{
assert(ps);
while (ps->front)
{
QList* nextfront = ps->front->next;
free(ps->front);
ps->front = nextfront;
}
ps->front = ps->rear = NULL;
ps->size = 0;
}
3、主函数测试
#include "Queue.h"
int main()
{
Queue Q;
QInit(&Q);
QPush(&Q, 1);
QPush(&Q, 2);
QPush(&Q, 3);
QPush(&Q, 4);
printf("队列入队顺序为1,2,3,4,出队顺序也应该为1,2,3,4\n");
while (!QEmpty(&Q))
{
QDataType x = QFront(&Q);
printf("%d ", x);
QPop(&Q);
}
QDestory(&Q);
return 0;
}
分别建立名为Queue.h的头文件和Queue.c的源文件,和一个主函数文件。运行上述代码: