队列的定义:
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
队列的顺序存储实现:
队列的顺序存储通常由一个一维数组,一个记录队头的变量front,一个记录队尾的变量rear和一个记录队列大小的变量 MaxSize组成。结构如下:
#define QDataType int
typedef struct Queue{//队列的结构
QDataType *queue;
QDataType front;
QDataType rear;
QDataType MaxSize;//队列大小
}Queue;
什么是环形队列?
rear指向队头元素,front为队尾元素的下标加一,rear 和 front 的初始值都为0;在实现队列的删除队头操作时,rear变量如何变化呢?如果不改变rear变量的值将队列的其他元素都向前移一位那么操作就很麻烦,所以我们直接让rear变量+1,既指向下一个元素。在实现插入队尾操后时,让front+1,当front 等于 MaxSize -1 时,让front等于 0,这样就形成了环形队列。
值得注意的是 我们如何判断环形链表是空还是满?
假设数组长度为n,队列的长度也为n那么队列满队列空 rear 和front 都相等无法判别。所以数组长度为n,队列的长度只能为 n-1。判定如下
bool is_QueueFull(Queue* q){// 检测队列是否为满
if(( q ->rear + 1 ) % q ->MaxSize == q ->front ){
return true;
}else{
return false;
}
}
bool is_QueueEmpty(Queue* q){// 检测队列是否为空
if(q ->front == q ->rear ){
return true;
}else{
return false;
}
}
队列的链式存储实现:
队列的链式存储一般不设置队列的大小,它由一个标志队头的元素 front 和一个标志链尾的元素rear组成。初始状态 rear和front都为空。结构如下:
#define QDataType int
typedef struct Node{//节点结构
struct Node* next;
QDataType data;
}Node;
typedef struct Queue{//队列的结构
Node* front;
Node* rear;
}Queue;
顺序存储实现代码:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define QDataType int
typedef struct Queue{//队列的结构
QDataType *queue;
QDataType front;//指向队头
QDataType rear;//指向队尾的下一个元素
QDataType MaxSize;//队列大小
}Queue;
Queue* QueueInit(QDataType MaxSize);// 初始化队列
void QueuePush(Queue* q, QDataType data);// 队尾入队列
void QueuePop(Queue* q);// 队头出队列
bool is_QueueEmpty(Queue* q);// 检测队列是否为空
bool is_QueueFull(Queue* q);// 检测队列是否为满
void QueueDestroy(Queue* q);// 销毁队列
QDataType QueueFront(Queue* q);//获取队列队头元素
QDataType Queuerear(Queue* q);//获取队列队尾元素
Queue* QueueInit(QDataType MaxSize){// 初始化队列
Queue* q = (Queue*)malloc(sizeof(Queue));
q ->queue = (QDataType *)malloc(sizeof(QDataType));
q ->front = q ->rear = 0;
q ->MaxSize = MaxSize;
return q;
}
void QueuePush(Queue* q, QDataType data){// 队尾入队列
if( is_QueueFull(q) ){
printf("队列满");
}else{
q ->queue[( q ->rear ) ++] = data;
q ->rear = (q ->rear) % (q ->MaxSize);
}
}
void QueuePop(Queue* q){// 队头出队列
if( is_QueueEmpty(q) ){
printf("队列空");
}else{
q ->front ++;
q ->front = ( q ->front ) % ( q ->MaxSize);
}
}
bool is_QueueFull(Queue* q){// 检测队列是否为满
if(( q ->rear + 1 ) % q ->MaxSize == q ->front ){
return true;
}else{
return false;
}
}
bool is_QueueEmpty(Queue* q){// 检测队列是否为空
if(q ->front == q ->rear ){
return true;
}else{
return false;
}
}
QDataType QueueFront(Queue* q){
if(is_QueueEmpty(q)){
printf("队列为空");
}else{
return (q ->queue)[q ->front];
}
}
QDataType Queuerear(Queue* q){//获取队列队尾元素
if(is_QueueEmpty(q)){
printf("队列为空");
}else{
if( q ->rear == 0){
return (q ->queue)[(q ->MaxSize) -1 ];
}else{
return (q ->queue)[(q ->rear) - 1 ];
}
}
}
void QueueDestroy(Queue* q){// 销毁队列
free(q ->queue);//
free(q);
}
链式存储实现代码:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define QDataType int
typedef struct Node{//节点结构
struct Node* next;
QDataType data;
}Node;
typedef struct Queue{//队列的结构
Node* front;
Node* rear;
}Queue;
// 初始化队列
void QueueInit(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QDataType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QDataType QueueFront(Queue* q);
// 获取队列队尾元素
QDataType Queuerear(Queue* q);
// 检测队列是否为空
bool is_QueueEmpty(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);
Queue* QueueInit(){//队列初始化
Queue* q = (Queue*)malloc(sizeof(Queue));
q ->front = q ->rear =NULL;
return q;
}
// 队尾入队列
void QueuePush(Queue* q, QDataType data){
assert(q);//队列不存在
Node* ptr = (Node*)malloc(sizeof(Node));
ptr ->data = data;
ptr ->next = NULL;
if(is_QueueEmpty(q)){//队列为空
q ->front = q ->rear = ptr;
}else{
q ->rear ->next = ptr;
q ->rear = ptr;
}
}
// 队头出队列
void QueuePop(Queue* q){
if(is_QueueEmpty(q)){
printf("队列空");
}else{
Node* ptr = q ->front;
q ->front =q ->front ->next;
if(q ->front == NULL){
q ->rear = q ->front;
}
free(ptr);
}
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool is_QueueEmpty(Queue* q){
assert(q);
if(q ->front == NULL){
return true;
}else{
return false;
}
}
// 获取队列头部元素
QDataType QueueFront(Queue* q){
assert(q);
if(is_QueueEmpty(q)){
printf("队列空\n");
}else{
return q ->front ->data;
}
}
// 获取队列队尾元素
QDataType Queuerear(Queue* q){
assert(q);
if(is_QueueEmpty(q)){
printf("队列空\n");
}else{
return (q ->rear)->data;
}
}
// 销毁队列
void QueueDestroy(Queue* q){
assert(q);
while(!is_QueueEmpty(q)){
QueuePop(q);
}
free(q);
}