基础结构之循环队列

发布于:2022-11-09 ⋅ 阅读:(9) ⋅ 点赞:(0) ⋅ 评论:(0)

一、循环队列基本要点

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);

}