一、循环队列基本要点
1、队列的定义
这里我们需要注意的一点是,我们在队尾进行元素的插入,在队头进行元素的删除
2、引入循环队列的思想
我们都知道顺序栈的插入和删除时间复杂度都为O(1),但是顺序队列的尾部插入是O(1),头部删除却需要O(n),因此我们引入了循环队列的思想
循环队列的思想我们基本了解了,那之前在c语言的学习中,其实我们发现,有些编程题目已近体现了循环队列的思想了:这里,我们简单的举两个例子1)约瑟夫环2)魔方阵,具体内容大家可以下去查看一下
3、学好循环队列,解决三个难点
1)难点一:我们前面已经解决过了,现在具体描述一下
2)难点二:循环队列当判空判满都为front == rear ,我们如何将判空判满区别开
3)难点三:如何O(1)时间获取循环队列的有效长度(笔试重点)
总结:无论是 front>rear 还是 front<rear 都可以用总的公式:
(rear-front+MAX_SIZE)%MAX_SIZE 解决
二、代码实现循环队列
Queue.h头文件声明
#pragma once
typedef int ELEM_TYPE;
#define MAX_SIZE 100
typedef struct Queue {
ELEM_TYPE* base ;
int front;
int rear;
}Queue,*PQueue;
//初始化
void Init_queue(struct Queue* qu);
//入队
bool Push(struct Queue* qu, ELEM_TYPE val);
//出队
bool Pop(struct Queue* qu);
//获取队头元素值
ELEM_TYPE Top(struct Queue* qu);
//搜索
ELEM_TYPE search(struct Queue* qu, ELEM_TYPE val);
//判空
bool Is_Empty(struct Queue* qu);
//判满
bool Is_Full(struct Queue* qu);
//清空
void Clear(struct Queue* qu);
//销毁
void Destory(struct Queue* qu);
//获取有效值个数
int Get_length(struct Queue* qu);
//打印
void Show(struct Queue* qu);
Queue.cpp文件进行具体代码实现
#include<stdio.h>
#include"Queue.h"
#include<cassert>
#include <stdlib.h>
#define MAX_SIZE 100
//初始化
void Init_queue(struct Queue* qu) {
assert(qu != NULL);
qu->base = (ELEM_TYPE*)malloc(sizeof(ELEM_TYPE) * MAX_SIZE);
qu->rear = qu->front=0;
}
//入队
bool Push(struct Queue* qu, ELEM_TYPE val) {
assert(qu != NULL);
if (Is_Full(qu)) {
return false;
}
qu->base[qu->rear] = val;
qu->rear = (qu->rear + 1) % MAX_SIZE;//尾指针注意不要忘记向后走一步,但是不能用++
return true;
}
//出队
bool Pop(struct Queue* qu) {
assert(qu != NULL);
if (Is_Empty(qu)) {
return false;
}
assert(qu != NULL);
qu->front = (qu->front + 1) % MAX_SIZE;
return true;
}
//获取队头元素值
ELEM_TYPE Top(struct Queue* qu) {
if (Is_Empty(qu)) {
printf("error\n");
exit(1);
}
assert(qu != NULL);
return qu->base[qu->front];
}
//搜索
ELEM_TYPE search(struct Queue* qu, ELEM_TYPE val) {
assert(qu != NULL);
//从队头访问到对尾巴
for (int i = qu->front; i != qu->rear; i = (i + 1) % MAX_SIZE) {
if (qu->base[i] == val) {
return i;
}
}
return -1;
}
//判空
bool Is_Empty(struct Queue* qu) {
assert(qu != NULL);
if (qu->front == qu->rear) {
return true;
}
return false;
}
//判满
bool Is_Full(struct Queue* qu) {
assert(qu != NULL);
if ((qu->rear + 1)%MAX_SIZE == qu->front) {
return true;
}
return false;
}
//清空
void Clear(struct Queue* qu) {
assert(qu != NULL);
qu->base = 0;
qu->front = 0;
}
//销毁
void Destory(struct Queue* qu) {
assert(qu != NULL);
free(qu);
}
//获取有效值个数
int Get_length(struct Queue* qu) {
assert(qu != NULL);
return (qu->rear - qu->front + MAX_SIZE) % MAX_SIZE;
}
//打印
void Show(struct Queue* qu) {
assert(qu != NULL);
for (int i = qu->front; i != qu->rear; i = (i + 1) % MAX_SIZE) {
printf("%d ", qu->base[i]);
}
printf("\n");
}
main函数测试
int main() {
struct Queue head;
Init_queue(&head);
for (int i = 0; i <10; i++) {
Push(&head, i+1);
}
Show(&head);
printf("f=%d,r=%d\n", head.front, head.rear);
Pop(&head);
Show(&head);
int res = Get_length(&head);
printf("%d\n", res);
printf("f=%d,r=%d\n", head.front, head.rear);
ELEM_TYPE sum= Top(&head);
printf("%d\n", sum);
int j=search(&head, 5);
printf("%d\n", j);
}