目录
一、队列的概念
二、队列的实现
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的源文件,和一个主函数文件。运行上述代码: