主程序 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|
队列未满,可以继续添加元素
本程序只用于学习参考之用,转载请注明出处。
记得点赞哦
-