数据结构——环形队列的原理(模拟环形队列)

数据结构——环形队列的原理(模拟环形队列)
知识点简要介绍:
队列:一种特殊的线性表,包含队列头、队列尾,只允许在队列头进行删除操作,在队列为进行删除操作
分类:
    顺序队列、循环队列(环形队列)
顺序队列:
    在内存中是一段连续的存储空间,并有队列头指针和队列尾指针,打个比喻吧:
    顺序队列就像在排队买车票,排在最前面(第一个人)的就是队头,排在最后的就是队尾,第一个买完票,离开(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
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
using namespace std;
//#include
//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


队列可运用于任何类型之中,如,将上述代码改变一下便可将队列运用于类


Customer.h
#ifndef CUSTOMER_H
#define CUSTOMER_H
//----------------
#include
//#include
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
#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
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
using namespace std;
//#include
//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

//-----------------------------------------
可以看出队列中的元素可以是任何类型,包括基本数据类型,类类型,自定义类型等,也可以通过做成模板来适应不同的类型,对否?.......确实如此吧~

你可能感兴趣的:(数据结构,C++学习总结)