上篇博客,学习了栈,我们可以知道他也是一种线性表,遵从先进后出的原则,在本节,我们进一步学习另一种线性表—队列。就像饭堂里排队打饭的的队伍,作为一种先进先出的线性表,他又有哪些特别之处呢?又该如何应用呢?接下来,跟我走近队列的世界里。
目录
一、队列的应用场景
二、队列的基本概念和结构
2.1 队列的基本概念
2.2 队列的结构
2.3 队列的实现方式
三、循环队列栈的接口函数实现
3.0 循环队列设计的思想来源
3.0.1 从数组存放的角度分析
3.0.2 从时间复杂度的角度分析
3.1 循环队列的三个关键问题及如何解决?
总结:
3.2 循环队列的特点
3.3 循环队列的接口函数
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "queue.h"
//初始化
void Init_Queue(struct Queue* que);
//入队
void Push(struct Queue* que, ELEM_TYPE val);
//出队
void Pop(struct Queue* que);
//获取队头元素值
ELEM_TYPE Front(struct Queue* que);
//获取有效元素个数
int Get_length(struct Queue* que);
//判空
bool IsEmpty(struct Queue* que);
//判满
bool IsFull(struct Queue* que);
//清空
void Clear(struct Queue* que);
//销毁
void Destroy(struct Queue* que);
//打印
void Show(struct Queue* que);
3.4 循环队列的设计(结构体)
//循环队列的结构体设计
#define MAX_SIZE 10
typedef int ELEM_TYPE;
typedef struct Queue
{
ELEM_TYPE *base;
int front; //队头指针
int rear; //队尾指针
}Queue, *PQueue;
3.5 循环队列的初始化
//初始化
void Init_Queue(struct Queue* que)
{
第0步:参数检测
assert(que!=NULL);
第1步:初始化赋值
que->base = (ELEM_TYPE *)malloc(MAX_SIZE * sizeof(ELEM_TYPE));
que->front = que->rear =0;
}
3.6 入队
//入队
void Push(struct Queue* que, ELEM_TYPE val)
{
第0步:参数检测
assert(que!=NULL);
//1.判满
if(IsFull(que))
{
return;
}
//2.给rear指向的下标赋值,进行入队操作
que->base[que->rear] = val;
//3.rear++(这里需要注意越界)
que->rear = (que->rear+1)%MAX_SIZE;
}
3.7 出队
//出队
void Pop(struct Queue* que)
{
第0步:参数检测
assert(que!=NULL);
//1.判空
if(IsEmpty(que))
{
return;
}
//2.让队头指针向后挪动一下,但是注意越界
que->front = (que->front+1)%MAX_SIZE;
}
3.8 获取队头元素值
//获取队头元素值
ELEM_TYPE Front(struct Queue* que)
{
第0步:参数检测
assert(que!=NULL);
return que->base[que->front];
}
3.9 获取有效元素个数
//获取有效元素个数
int Get_length(struct Queue* que)
{
第0步:参数检测
assert(que!=NULL);
return ((que->rear-que->front)+MAX_SIZE)%MAX_SIZE;
}
3.10 判空
//判空
bool IsEmpty(struct Queue* que)
{
第0步:参数检测
assert(que!=NULL);
return que->front == que->rear;
}
3.11 判满
//判满
bool IsFull(struct Queue* que)
{
第0步:参数检测
assert(que!=NULL);
return (que->rear + 1)%MAX_SIZE == que->front;
}
3.12 扩容(无法直接扩容!循环队列的最致命缺陷)
3.13 打印
//打印
void Show(struct Queue* que)
{
第0步:参数检测
assert(que!=NULL);
for(int i=que->front; i!=que->rear; i=(i+1)%MAX_SIZE)
{
printf("%d ", que->base[i]);
}
printf("\n");
}
3.14 清空
//清空
void Clear(struct Queue* que)
{
第0步:参数检测
assert(que!=NULL);
que->front = que->rear = 0;
}
3.15 销毁
//销毁
void Destroy(struct Queue* que)
{
第0步:参数检测
assert(que!=NULL);
que->front = que->rear = 0;
free(que->base);
que->base = NULL;
}
四、总结
以上便是我为大家带来的循环队列设计内容,若有不足,望各位大佬在评论区指出,谢谢大家!下一节继续进行链式队列的内容,感兴趣的你可以留下你们的点赞、收藏和关注,这是对我极大的鼓励,我也会更加努力创作更优质的作品。再次感谢大家!