来自C语言版数据结构:介绍关于循环队列的建立,入队,出队,求队长, 取队头元素操作。
循环队列
队列的一种顺序存储方式, 为什么叫循环队列 ? 第一:防止 "假溢出", 这是由队的操作造成 "队尾进, 队头出"。 很可能在其他位置还有空间, 但是却报错了(越界)具体措施: 书上是利用模运行(%)去解决的, 呈现出环状时候,就不会出现 "假溢出" 的情况提示:以下是本篇文章正文内容,下面案例可供参考
一、采用CLion写代码的感觉
CLion是基于C/C++ 的一种工具,小编就是利用这个编译的本篇文章, 个人感觉: 高级, 很麻烦, 但是功能却齐全,比如:你引入一个库, 但是你没有用它里面的函数, 它会成灰色, 而不会呈现彩色, 更加严谨化了, 它提示你了, 不要浪费内存,占用资源。
二、队列的基本操作
1.建立和初始化
代码如下(示例):
// 建立队列
typedef struct Queue{
char sa[MAX]; //存储数据
int rear; //对尾指针
int front; //对头指针
}SQueue;
//初始化队列
SQueue *initQueue()
{
SQueue *Q;
Q = (struct Queue*)malloc(sizeof(struct Queue)); //申请内存空间
Q->front = 0;
Q->rear = 0;
return Q; //返回初始化的队列
}
初始化和建立的核心: 队尾和队头指向0 and 申请空间
2.入队
//入队
void push(SQueue *p, char x)
{
if((p->rear + 1) % MAX == p->front) //判断对满的条件
{
printf("对满");
exit(0);
}
p->sa[p->rear] = x; //队尾进
p->rear = (p->rear + 1) % MAX;
//利用模运算, 防止假溢出的情况
}
核心:原本是队尾指针+1便可, 但是为了防止溢出, 就采用模运算,形成环状。
3.出队
//出队
char pop(SQueue *p)
{
if(p->rear == p->front) //判断队空的条件
{
printf("对空");
exit(0);
}
char e = p->sa[p->front]; //用于存储出队的元素
p->front = (p->front + 1) % MAX;
return e;
}
核心:与入队一样, 只不过判断条件和多了一步返回值, 对头出,对头指针+1,
采用模运算。
4.取队头元素和队列长度
//取循环队列的长度
int queuelength(SQueue *p)
{
return (p->rear - p->front + MAX) % MAX;
//作用:加了一个绝对值, 记忆它
}
//取循环队列的队头元素
char GetHead(SQueue *p)
{
if(p->rear == p->front) //判断对空的条件
{
exit(0);
}
char e;
e = p->sa[p->front]; //出队列一样, 只不过不用移动尾指针
return e;
}
代码实现
//
// Created by xhh on 2021/6/30.
//
//循环队列的基本操作
#include<stdio.h>
#include<stdlib.h>
#define MAX 5 //循环队列的最大长度
typedef struct Queue{
char sa[MAX]; //存储数据
int rear; //队尾指针
int front; //队头指针
}SQueue;
//创建一个队列
SQueue *initQueue()
{
SQueue *Q;
Q = (struct Queue*)malloc(sizeof(struct Queue));
Q->front = 0;
Q->rear = 0;
return Q;
}
//入队
void push(SQueue *p, char x)
{
if((p->rear + 1) % MAX == p->front)//利用模运算, 防止假溢出的情况
{
printf("对满");
exit(0);
}
p->sa[p->rear] = x; //队尾进
p->rear = (p->rear + 1) % MAX;
}
//出队
char pop(SQueue *p)
{
if(p->rear == p->front)
{
printf("对空");
exit(0);
}
char e = p->sa[p->front];
p->front = (p->front + 1) % MAX;
return e;
}
//取循环队列的长度
int queuelength(SQueue *p)
{
return (p->rear - p->front + MAX) % MAX;
}
//取循环队列的队头元素
char GetHead(SQueue *p)
{
if(p->rear == p->front)
{
exit(0);
}
char e;
e = p->sa[p->front];
return e;
}
//打印函数
void display(SQueue *p)
{
int index = p->front; //队头指针
while(p->rear != index)
{
printf("%c->", p->sa[index]);
index = (index + 1) % MAX;
}
}
int main()
{
SQueue *A; //生成一个队列
A = initQueue(); //初始化
printf("入队:");
for(char i = 'A'; i <= 'D'; i++)
{
push(A, i); //入队
}
display(A);
printf("\n队长:%d\n", queuelength(A));
printf("头元素:%c\n", GetHead(A));
printf("出队:");
for(int i = 0; i < 4; i++)
{
printf("%c->", pop(A));
}
system("pause");
return 0;
}
结果:
入队:A->B->C->D->
队长:4
头元素:A
出队:A->B->C->D->
编译工具的推荐:小白学习C语言,我还是推荐用VS, 操作简单且方便。
循环队列:其实是一种顺序存储结构,采用模运算,实现了对头尾相连,本质上还是数组,只不过在移动指针运算上改变了, 还是以数组的形式存储。