C++ 顺序队列

主程序 main.cpp

//Written by Xuebi
//顺序队列,先进先出,后进后出(循环),区别与上一文章先进后出,后进先出,而且引入了循环概念
#include <iostream>
#include "My_Stack.h"
using namespace std;
int main()
{
    MyStack<int> st(4);//利用长度为4的Stack数组进行解释,Front=Rear=0
    st.Push(10);//Rront=0,Rear=1
    st.Push(20);//Rront=0,Rear=2
    st.Push(30);//Rront=0,Rear=3,此时队列已满
    cout << st.F_Front() <<"  "<<st.F_Rear()<< endl;//结果:10 30
    st.Push(40);//Stack数组扩大一倍,此时Size=8,Front=7,Rear=2
    cout << st.F_Front() <<"  "<<st.F_Rear()<< endl;//结果:10 40
    st.Push(50);//Front=7,Rear=3
    st.Pop();//在队首删除数据
    cout << st.F_Front() <<"  "<<st.F_Rear()<< endl;//结果:20 50
    return 0;
}

头文件 My_Stack.h

#ifndef MY_STACk_H
#define MY_STACk_H
#include <iostream>
#include <stdlib.h>
using namespace std;
template<class T>
class MyStack
{
private:
    int Front;
    int Rear;//初始化时Front=Rear=0
    int Size;
    T*Stack;
public:
    MyStack(int StackSize);
    ~MyStack();
    Pop();
    Push(const T&items);//在Stack数组中Front+1位置添加数据,注意本程序中Front位置特意留空不赋值
    T&F_Front()const;//在Stack数组中输出Front+1位置的数据
    T&F_Rear()const;//在Stack数组中输出Rear位置的数据
    bool IsEmpty()const;//Rear=Front时Stack为空,返回1,否则返回0
};
template<class T>//Stack类的构造函数
MyStack<T>::MyStack(int StackSize):Size(StackSize)
{
    Stack=new T[StackSize];
    Rear=Front=0;
}
template<class T>//Stack的析构函数
MyStack<T>::~MyStack()
{
    delete []Stack;
}
template<class T>
bool MyStack<T>::IsEmpty()const
{
    if(Rear==Front)//例如初始化后Rear=Front=0,此时为空
        return 1;
    else
        return 0;
}
template<class T>
T&MyStack<T>::F_Front()const
{
    if(IsEmpty())
    {
        cout<<"This Stack is empty, cannot F_Front(), over"<<endl;
        exit(1);
    }
    else
    return Stack[(Front+1)%Size];//下位为Front的位置一直为空,Front+1位置才真是“第一个”数据
}
template<class T>
T&MyStack<T>::F_Rear()const
{
    if(IsEmpty())
    {
        cout<<"This Stack is empty, cannot F_Rear(), over"<<endl;
        exit(1);
    }
    else
    return Stack[Rear%Size];
}
template<class T>//在Stack数组队首中删除数据
MyStack<T>::Pop()
{
    if(IsEmpty())
    {
        cout<<"This Stack is empty, cannot Pop(), over"<<endl;
        exit(1);
    }
    else
    {
        Stack[Front+1].~T();//这行针对Stack数组里的数据为类,用于析构类
        Front++;
    }
}
template<class T>
MyStack<T>::Push(const T&items)//往Stack中添加数据
{
    if(((Rear+1)%Size)==(Front%Size))//检验队列是否已满,若队列满,则扩大数组,注意Front位置留空
    {
        T*a=new T[Size*2];
        int Start=(Front+1)%Size;//下面进行拷贝,技巧:在拷贝后的数组a中,始终把Front(留空)放在2*Size-1位置,即末尾
        if(Start<2)
        {//情况一,Front的位置在Stack的Size-1位置或者0位置,此时可以讲Stack数组正常拷贝到a数组
            copy(Stack+Start,Stack+Start+Size-1,a);
        }
        else
        {//情况二,Front的位置不是上面两种情况,则需要分段拷贝
            copy(Stack+Start,Stack+Size,a);
            copy(Stack,Stack+(Rear%Size)+1,a+Size-Start);
        }
        delete []Stack;
        Stack=a;
        Rear=Size-2;//Rear位置,原本未扩充前Stack数组含有Size-1个数据(Front留空)
        Front=2*Size-1;//Front位置
        Size=2*Size;
    }
    else//队列没满直接添加数据
    {
        Rear=(Rear)%Size+1;
        Stack[Rear]=items;
    }
}
#endif //MY_STACK-H```

队列已满的情况
f:Front 
r:Rear
情况1
|空-f|A|B|C-r|
|A|B|C-r|空_f|
情况1可以从Front+1开始完整拷贝

情况2
|C-r| 空-f |A|B|
|B|C-r|空-f|A|
情况2要分段拷贝

扩大数组再拷贝后得到
|A|B|C-r|空|空|空|空|空-f|
队列未满,可以继续添加元素


本程序只用于学习参考之用,转载请注明出处。
记得点赞哦






-
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值