数据结构——环形队列的原理(模拟环形队列)
知识点简要介绍:
队列:一种特殊的线性表,包含队列头、队列尾,只允许在队列头进行删除操作,在队列为进行删除操作
分类:
顺序队列、循环队列(环形队列)
顺序队列:
在内存中是一段连续的存储空间,并有队列头指针和队列尾指针,打个比喻吧:
顺序队列就像在排队买车票,排在最前面(第一个人)的就是队头,排在最后的就是队尾,第一个买完票,离开(FIFO,先进先出,先排队的先走),第二个人变成了队头,整体队列前进,每走一个人,整个队列都要前进,可见整体性能不会多么的好
环形队列:
可以将队列空间想象成一个环形空间,这能使队列空间重复使用:无论插入还是删除,front(队头)指针增1或front(队尾)指针加1时超出所分配的空间,就让它指向这片连续空间的起始地址
FIFO(先进先出)
取元素时先从队列头开始,取完后,下一个元素就成了队列头,依次循环
只有一个元素时,既是队列头,也是队列尾
--环形队列的实现原理(模拟队列的实现方式)
入队算法:
头指针head、尾指针tail
1.tail++;
2.若tail = n + 1; 则tail = 1;
3.若head = tail, 即头尾指针重合,队列已满 或 队列只有一个元素;
4.初始化队列、入队、出队、读队、判空、判满
模拟开始:
MyQueue.h
MyQueue.cpp
Demo.cpp
//控制台运行结果:
30
20
10
40
30
20
30
20
Customer.cpp
MyQueue.h
Myqueue.cpp
Demo.cpp
//控制台运行结果:
姓名:L
年龄:20
姓名:C
年龄:21
姓名:D
年龄:22
要删除的队列头:
姓名:L
年龄:20
要删除后对列:
姓名:C
年龄:21
姓名:D
年龄:22
//-----------------------------------------
可以看出队列中的元素可以是任何类型,包括基本数据类型,类类型,自定义类型等,也可以通过做成模板来适应不同的类型,对否?.......确实如此吧~
知识点简要介绍:
队列:一种特殊的线性表,包含队列头、队列尾,只允许在队列头进行删除操作,在队列为进行删除操作
分类:
顺序队列、循环队列(环形队列)
顺序队列:
在内存中是一段连续的存储空间,并有队列头指针和队列尾指针,打个比喻吧:
顺序队列就像在排队买车票,排在最前面(第一个人)的就是队头,排在最后的就是队尾,第一个买完票,离开(FIFO,先进先出,先排队的先走),第二个人变成了队头,整体队列前进,每走一个人,整个队列都要前进,可见整体性能不会多么的好
环形队列:
可以将队列空间想象成一个环形空间,这能使队列空间重复使用:无论插入还是删除,front(队头)指针增1或front(队尾)指针加1时超出所分配的空间,就让它指向这片连续空间的起始地址
FIFO(先进先出)
取元素时先从队列头开始,取完后,下一个元素就成了队列头,依次循环
只有一个元素时,既是队列头,也是队列尾
--环形队列的实现原理(模拟队列的实现方式)
入队算法:
头指针head、尾指针tail
1.tail++;
2.若tail = n + 1; 则tail = 1;
3.若head = tail, 即头尾指针重合,队列已满 或 队列只有一个元素;
4.初始化队列、入队、出队、读队、判空、判满
模拟开始:
MyQueue.h
#ifndef MY_QUEUE
#define MY_QUEUE
//-----------------
class MyQueue{
public:
MyQueue(int queueCapacity);//创建队列的容量
virtual ~MyQueue();//销毁队列
void clearQueue();//清空队列
bool queueEmpty() const;//判空
bool queueFull() const;//判满
int queueLength() const;//长度
bool enQueue(int element);//入队
bool dequeue(int &element);//首元素出队
void queueTraverse();//遍历队列
private:
int *m_pQueue;//队列数组指针
int m_iQueueLen;//个数
int m_iQueueCapacity;//容量
int m_iHead;
int m_iTail;
};
#endif MY_QUEUE
MyQueue.cpp
#include"MyQueue.h"
#include<iostream>
using namespace std;
//---------------------------------
MyQueue::MyQueue(int queueCapacity){
m_iQueueCapacity = queueCapacity;
m_iHead = 0;
m_iTail = 0;
m_iQueueLen = 0;
m_pQueue = new int[m_iQueueCapacity];
}
MyQueue::~MyQueue(){
delete []m_pQueue;
m_pQueue = NULL;
}
void MyQueue::clearQueue(){
m_iHead = 0;
m_iTail = 0;
m_iQueueLen = 0;
}
bool MyQueue::queueEmpty() const{
return m_iQueueLen == 0 ? true : false;
}
bool MyQueue::queueFull() const{
return m_iQueueLen == m_iQueueCapacity ? true : false;
}
int MyQueue::queueLength() const{
return m_iQueueLen;
}
bool MyQueue::enQueue(int element){
if(queueFull()){
return false;
}
else{
m_pQueue[m_iTail] = element;//插入元素到队列尾
m_iTail++;
m_iTail = m_iTail % m_iQueueCapacity;
m_iQueueLen++;
return true;
}
}
bool MyQueue::dequeue(int &element){
if(queueEmpty()){
return false;
}
else{
element = m_pQueue[m_iHead];
m_iHead++;
m_iHead = m_iHead % m_iQueueCapacity;
m_iQueueLen--;
return true;
}
}
void MyQueue::queueTraverse(){
for(int i = m_iHead; i < m_iQueueLen + m_iHead; i++){//因为i的初始值是不断变化的,条件判断应该加上m_iHead
cout << m_pQueue[i % m_iQueueCapacity] << endl;
}
cout << endl;
}
Demo.cpp
#include"MyQueue.h"
#include<iostream>
using namespace std;
//#include<iostream>
//using namespace std;
//--------------------
int main(){
MyQueue *p = new MyQueue(4);
p->enQueue(30);
p->enQueue(20);
p->enQueue(10);
p->enQueue(40);
p->queueTraverse();
int e = 0;
p->dequeue(e);
cout << e << endl;
p->dequeue(e);
cout << e << endl;
p->clearQueue();
p->queueTraverse();
p->enQueue(30);
p->enQueue(20);
p->queueTraverse();
}
//控制台运行结果:
30
20
10
40
30
20
30
20
队列可运用于任何类型之中,如,将上述代码改变一下便可将队列运用于类
#ifndef CUSTOMER_H
#define CUSTOMER_H
//----------------
#include<string>
//#include<iostream>
using namespace std;
//----------------
class Customer{
public:
Customer(string name = "", int age = 0);
void printInfo() const;
private:
string m_strName;
int m_iAge;
};
#endif CUSTOMER_H
Customer.cpp
#include<iostream>
#include"Customer.h"
using namespace std;
//------------------
Customer::Customer(string name, int age){
m_strName = name;
m_iAge = age;
}
void Customer::printInfo() const{
cout << "姓名:" << m_strName << endl;
cout << "年龄:" << m_iAge << endl;
cout << endl;
}
MyQueue.h
#ifndef MY_QUEUE
#define MY_QUEUE
//-----------------
#include"Customer.h"
//----------------
class MyQueue{
public:
MyQueue(int queueCapacity);//创建队列的容量
virtual ~MyQueue();//销毁队列
void clearQueue();//清空队列
bool queueEmpty() const;//判空
bool queueFull() const;//判满
int queueLength() const;//长度
bool enQueue(Customer element);//入队
bool dequeue(Customer &element);//首元素出队
void queueTraverse();//遍历队列
private:
Customer *m_pQueue;//队列数组指针
int m_iQueueLen;//个数
int m_iQueueCapacity;//容量
int m_iHead;
int m_iTail;
};
#endif MY_QUEUE
Myqueue.cpp
#include"MyQueue.h"
#include<iostream>
using namespace std;
//---------------------------------
MyQueue::MyQueue(int queueCapacity){
m_iQueueCapacity = queueCapacity;
m_iHead = 0;
m_iTail = 0;
m_iQueueLen = 0;
m_pQueue = new Customer[m_iQueueCapacity];
}
MyQueue::~MyQueue(){
delete []m_pQueue;
m_pQueue = NULL;
}
void MyQueue::clearQueue(){
m_iHead = 0;
m_iTail = 0;
m_iQueueLen = 0;
}
bool MyQueue::queueEmpty() const{
return m_iQueueLen == 0 ? true : false;
}
bool MyQueue::queueFull() const{
return m_iQueueLen == m_iQueueCapacity ? true : false;
}
int MyQueue::queueLength() const{
return m_iQueueLen;
}
bool MyQueue::enQueue(Customer element){
if(queueFull()){
return false;
}
else{
m_pQueue[m_iTail] = element;//插入元素到队列尾
m_iTail++;
m_iTail = m_iTail % m_iQueueCapacity;
m_iQueueLen++;
return true;
}
}
bool MyQueue::dequeue(Customer &element){
if(queueEmpty()){
return false;
}
else{
element = m_pQueue[m_iHead];
m_iHead++;
m_iHead = m_iHead % m_iQueueCapacity;
m_iQueueLen--;
return true;
}
}
void MyQueue::queueTraverse(){
for(int i = m_iHead; i < m_iQueueLen + m_iHead; i++){//因为i的初始值是不断变化的,条件判断应该加上m_iHead
m_pQueue[i % m_iQueueCapacity].printInfo();
}
cout << endl;
}
Demo.cpp
#include"MyQueue.h"
#include<iostream>
using namespace std;
//#include<iostream>
//using namespace std;
//--------------------
#include"Customer.h"
//--------------------
int main(){
MyQueue *p = new MyQueue(4);
Customer c1("L", 20);
Customer c2("C", 21);
Customer c3("D", 22);
p->enQueue(c1);
p->enQueue(c2);
p->enQueue(c3);
p->queueTraverse();
cout << "要删除的队列头:\n" << endl;
Customer c4("",0);
p->dequeue(c4);
c4.printInfo();
cout << "要删除后对列:\n" << endl;
p->queueTraverse();
}
//控制台运行结果:
姓名:L
年龄:20
姓名:C
年龄:21
姓名:D
年龄:22
要删除的队列头:
姓名:L
年龄:20
要删除后对列:
姓名:C
年龄:21
姓名:D
年龄:22
//-----------------------------------------
可以看出队列中的元素可以是任何类型,包括基本数据类型,类类型,自定义类型等,也可以通过做成模板来适应不同的类型,对否?.......确实如此吧~