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

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


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


Customer.h
#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

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

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Python中,可以使用标准库中的`collections`模块来实现环形队列。具体而言,可以使用`deque`类来创建一个环形队列对象。`deque`类提供了一个双向队列的实现,其中可以设置队列的最大长度,当队列满时,新的元素会从队头挤出,从而实现了环形队列的效果。 以下是使用Python实现环形队列的示例代码: ```python from collections import deque # 创建一个长度为5的环形队列 queue = deque(maxlen=5) # 向环形队列中添加元素 queue.append(1) queue.append(2) queue.append(3) queue.append(4) queue.append(5) # 输出环形队列中的元素 print(queue) # 输出:deque([1, 2, 3, 4, 5], maxlen=5) # 继续向环形队列中添加元素,新的元素会从队头挤出 queue.append(6) # 输出环形队列中的元素 print(queue) # 输出:deque([2, 3, 4, 5, 6], maxlen=5) # 从环形队列中移除一个元素 queue.popleft() # 输出环形队列中的元素 print(queue) # 输出:deque([3, 4, 5, 6], maxlen=5) ``` 通过使用`deque`类,我们可以方便地实现环形队列,解决了队列溢出的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [解决顺序队列的“假溢出”问题之环形队列循环队列)——Python实现](https://blog.csdn.net/heibuliuqiu_gk/article/details/103087302)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [环形队列(Python代码实现)](https://blog.csdn.net/moodfriend/article/details/127581089)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值