Circular Queue--循环队列

队列大家见得很多了,形式也比较简单,就是一个特化的链表,它的enqueue、dequeue操作相当于链表的addLast、removeFirst操作。关于链表的实现,可以查看我的另一篇博文--"LinkedList--链表"。下面仅讨论一个稍微复杂点的情况--循环队列。

循环队列的就是用循环数组来实现队列,有一个问题需要解决:在普通的非循环队列中,rear == front 说明队列为空队列,然而在循环队列中,这个可能意味着队列为空,也可能意味着队列为满。通常采用两种策略来处理这个问题。

1. 设置一个标识位,以区别队列是空还是满。可以这样认为:初始化的时候令 front = rear = 0,flag = 0代表空。通过enqueue 入队操作使得 front = rear,认为到达满状态,flag = 1;通过dequeue 出队操作使得 front = rear,认为到达空状态,flag = 0。

2. 少用一个元素空间,约定以“队列头指针在队列尾指针的下一位置(循环状态的下一位置)”作为判定队列满的标识。

策略1代码如下所示:

#ifndef _CIRQUEUE_H
#define _CIRQUEUE_H

#include <iostream>
#include <stdexcept>
using namespace std;

//MAXN个空间, 所有空间都可用
const int MAXN = 5;

template<typename T>
class cirQueue
{
private:
	bool isEmpty;
	T array[MAXN];
	int front,rear;
public:
	cirQueue();
	cirQueue(T *list,int SIZE);
	void enque(T e);
	T deque();
	int getSize();
	void print();
};

template<typename T>
cirQueue<T>::cirQueue() {
	front = rear = 0;
	isEmpty = 1;
}

template<typename T>
cirQueue<T>::cirQueue(T *list , int SIZE) {
	front = rear = 0;
	isEmpty = 1;
	if(SIZE > MAXN || SIZE < 0)
		throw runtime_error("Index out of range");
	for(int i = 0 ; i < SIZE ; i ++)
		enque(list[i]);
}

template<typename T>
//若队列非满,增加队尾元素
void cirQueue<T>::enque(T e) {
	if(rear == front && !isEmpty)
	{
		cout << "Already full !\n";
		return;
	}
	array[rear] = e;
	rear = (rear+1)%MAXN;
	if(rear == front)
		isEmpty = 0;
}

template<typename T>
//若队列非空,删除队头元素
T cirQueue<T>::deque() {
	if(rear == front && isEmpty)
	{
		throw runtime_error("Already empty !\n");
	}

	T ele = array[front];
	front = (front+1)%MAXN;
	if(rear == front)
		isEmpty = 1;
	return ele;
}

template<typename T>
int cirQueue<T>::getSize() {
	if(rear == front)
		return (isEmpty ? 0 : MAXN);
	else
		return (rear-front+MAXN) % MAXN;
}

template<typename T>
void cirQueue<T>::print() {
	int cnt = getSize();
	if(cnt == 0)
	{
		cout << "Empty Queue !\n";
		return;
	}
	int i=0,inde = front;
	while(i < cnt)
	{
		cout << array[inde] << " ";
		inde = (inde+1)%MAXN;
		i ++;
	}
	cout << endl;
}
#endif

策略2代码如下所示:

#ifndef _CIRQUEUE_H
#define _CIRQUEUE_H

#include <iostream>
#include <stdexcept>
using namespace std;

//101个空间,有一个空间不可用
const int MAXN = 101;

template<typename T>
class cirQueue
{
private:
	T array[MAXN];
	int front,rear;
public:
	cirQueue();
	cirQueue(T *list,int SIZE);
	void enque(T e);
	T deque();
	int getSize();
};

template<typename T>
cirQueue<T>::cirQueue() {
	front = rear = 0;
}

template<typename T>
cirQueue<T>::cirQueue(T *list , int SIZE) {
	front = rear = 0;
	if(SIZE >= MAXN-1)
		throw runtime_error("Index out of range");
	for(int i = 0 ; i < SIZE ; i ++)
		enque(list[i]);
}

template<typename T>
//若队列非满,增加队尾元素
void cirQueue<T>::enque(T e) {
	if((rear+1)%MAXN == front)
	{
		cout << "Already full !\n";
		return;
	}
	array[rear] = e;
	rear = (rear+1)%MAXN;
}

template<typename T>
//若队列非空,删除队头元素
T cirQueue<T>::deque() {
	if(rear == front)
	{
		throw runtime_error("Already empty !\n");
	}
	T ele = array[front];
	front = (front+1)%MAXN;
	return ele;
}

template<typename T>
int cirQueue<T>::getSize() {
	return (rear-front+MAXN) % MAXN;
}

#endif

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 23:38:27

Circular Queue--循环队列的相关文章

循环队列——队列的顺序表示和实现

參考书目:<数据结构(C语言版)>,严蔚敏 怎样将<数据结构>中的知识应用到如今的工作中呢(单片机C编程.数字信号处理算法),希望在这里可以得到各位的指点.这个程序是我自己用循环队列实现了一个简单的应用模型(得益于一位童鞋的启示).这里高手如云,希望可以得到很多其它的指点啊! common.h #ifndef _COMMON_H_ #define _COMMON_H_ #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR

循环队列的实现(出队,入队,遍历等)

队列的抽象数据类型定义为: 类型名称:队列. 数据对象集:一个有0个或多个元素的有穷线性表. 操作集:对于一个长度为正整数MaxSize的队列Q∈Queue, 记队列中的任一元素item∈ElementType,有: (1)Queue CreateQueue(int MaxSize):创建一个长度为MaxSize的空队列: (2)bool isEmpty(Queue Q):判断队列是否为空,若不空返回true(1),否则返回false(0): (3)void AddQ(Queue Q, Elem

循环队列(Circular Queue)

循环队列(Circular Queue) 1. 循环队列的概念 1.1 循环队列的定义 为了能够充分地使用数组中的存储空间,克服"假溢出"现象,可以把数组的前端和后端连接起来,形成一个环形的表,即把存储队列元素的表从逻辑上看成一个环,成为循环队列(circular queue). 1.2 循环队列中各元素的逻辑及存储关系 循环队列的首尾相接,当队头指针front和队尾指针rear进到maxSize-1后,再前进一个位置就自动到0.这可以利用除法取余的运算(%)来实现. (1)队头指针进

循环队列Circular Queue

循环队列:先进先出,从头出:front+1,从尾进:rear+1,空判断:front==rear,满判断(rear+1)%maxsize==front //循环队列的实现 //定义队列结构体 define MAXSIZE 100 typedef struct{ int *base; //存储内存分配基地址 int front; //队列头索引 int rear; //队列尾索引 }circularQueue; //队列初始化void InitQueue(circularQueue *q){ q-

[LeetCode] Design Circular Queue 设计环形队列

Design your implementation of the circular queue. The circular queue is a linear data structure in which the operations are performed based on FIFO (First In First Out) principle and the last position is connected back to the first position to make a

数据结构-队列(2)-循环队列

循环队列 此前,我们提供了一种简单但低效的队列实现. 更有效的方法是使用循环队列. 具体来说,我们可以使用固定大小的数组和两个指针来指示起始位置和结束位置. 目的是重用我们之前提到的被浪费的存储. 设计循环队列 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为"环形缓冲器".循环队列的一个好处是我们可以利用这个队列之前用过的空间.在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即

622.设计循环队列

设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为"环形缓冲器". 循环队列的一个好处是我们可以利用这个队列之前用过的空间.在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间.但是使用循环队列,我们能使用这些空间去存储新的值. 你的实现应该支持如下操作: MyCircularQueue(k): 构造器,设置队列长度为 k . Front: 从队首获取元素.如果队

设计循环队列——写起来最清爽的还使用原生的deque 双端队列

622. 设计循环队列 难度中等89收藏分享切换为英文关注反馈 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为“环形缓冲器”. 循环队列的一个好处是我们可以利用这个队列之前用过的空间.在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间.但是使用循环队列,我们能使用这些空间去存储新的值. 你的实现应该支持如下操作: MyCircularQueue(k): 构造器,设置队

数据结构之循环队列c语言实现

    队列是一种先入先出的结构,数据从队列头出,队尾进.在linux内核中进程调度,打印缓冲区都有用到队列.     队列有多种实现方式,可以用链表,也可以用数组.这里用数组来实现一个简单的循环队列.首先创建一个大小为8的队列如下,队列头尾指针指向同一块内存,          当从队列尾部插入一个数据后变成下面的情形,为了便于处理,这里始终会浪费一个空间 继续插入数据,直到出现以下情形,表示队列满了, 接下来看一下出队的情形,从队列头出队3个元素, 再添加三个元素后队列又变成满的了, 在上面