[数据结构]队列之顺序队列的类模板实现

队列是一种限定存取位置的线性表。同意插入的一端叫做队尾(rear),同意删除的一端叫做队首(front)。

队列具有FIFO的性质

队列的存储表示也有两种方式:基于数组的,基于列表的。基于数组的叫做顺序队列。基于列表的叫做链式队列。

一下是基于动态数组的顺序队列的模板类的实现。

顺序队列的抽象基类例如以下所看到的:仅仅提供了接口和显式的默认构造函数和析构函数,在派生类中调用。

#ifndef QUEUE
#define QUEUE
//队列的抽象基类

template<class T>
class Queue
{
public:
    Queue(){}
    ~Queue(){}
    virtual bool EnQueue(const T& x)=0;
    virtual bool DeQueue(T& x)=0;
    virtual bool getFront(T& x)const=0;
    virtual bool IsEmpty()const=0;
    virtual bool IsFull()const=0;
    virtual int getSize()const=0;
};

#endif

顺序队列的详细实现例如以下:(覆盖全部纯虚函数的接口。并提供自己的接口和数据成员)

/////////////////////////
#include"Stack.h"
#include <iostream>
//#include <cstdlib>
#include <cassert>
using namespace std;

template<class T>
class SeqQueue:public Queue<T>
{
public:
    SeqQueue(int sz=10):front(0),rear(0),maxSize(sz),elements(new T[sz]){assert(elements!=NULL);}
    ~SeqQueue(){delete []elements;}
    SeqQueue(const SeqQueue<T>& rhs);
    SeqQueue<T>& operator=(const SeqQueue<T>& rhs);

    bool EnQueue(const T& x);
    bool DeQueue(T& x);
    bool getFront(T& x)const;
    bool IsEmpty()const{return (rear==front)?true:false;}   //推断空
    bool IsFull()const{return ((rear+1)%maxSize==front)?true:false;}    //推断满
    int getSize()const{return (rear-front+maxSize)%maxSize;}    //检測大小。+maxSize表示非负

    void makeEmpty(){front=rear=0;}
    friend ostream& operator<< <T>(ostream& os,const SeqQueue<T>& rhs);//注意<T>

protected:
    int front,rear;
    T* elements;
    int maxSize;
};

template<class T>
bool SeqQueue<T>::EnQueue(const T& x)
{
    if(IsFull())
        return false;
    elements[rear]=x;
    rear=(rear+1)%maxSize;//注意不是++rear
    return true;
}

template<class T>
bool SeqQueue<T>::DeQueue(T& x)
{
    if(IsEmpty())
        return false;
    x=elements[front];
    front=(front+1)%maxSize;
    return true;
}

template<class T>
bool SeqQueue<T>::getFront(T& x)const
{
    if(IsEmpty())
        return false;
    x=elements[front];
    return true;
}

template<class T>
ostream& operator<<(ostream& os,const SeqQueue<T>& rhs)
{
    os<<"front="<<rhs.front<<" "<<"rear="<<rhs.rear<<endl;
    os<<"elements: ";
    for(int i=0;i<rhs.getSize();++i){
        os<<rhs.elements[(rhs.front+i)%rhs.maxSize]<<" ";   //注意遍历方法
    }
    os<<endl;
    return os;
}

template<class T>
SeqQueue<T>::SeqQueue(const SeqQueue<T>& rhs)
{
    front=rhs.front;
    rear=rhs.rear;
    maxSize=rhs.maxSize;

    T* dest=new T[maxSize];
    T* src=rhs.elements;
    elements=dest;

    for(int i=0;i<rhs.getSize();++i){
        dest[(front+i)%maxSize]=src[(front+i)%maxSize];
    }
}

template<class T>
SeqQueue<T>& SeqQueue<T>::operator=(const SeqQueue<T>& rhs)
{
    delete[] elements;
    makeEmpty();

    front=rhs.front;
    rear=rhs.rear;
    maxSize=rhs.maxSize;

    T* dest=new T[maxSize];
    T* src=rhs.elements;
    elements=dest;

    for(int i=0;i<rhs.getSize();++i){
        dest[(front+i)%maxSize]=src[(front+i)%maxSize];
    }

    return *this;
}

測试代码例如以下:

int main(int argc, char* argv[])
{
    SeqQueue<int> s(5);
    int a=1,b=2,c=3,d=4,e=0;
    s.EnQueue(a);
    s.EnQueue(b);
    s.EnQueue(c);
    s.EnQueue(d);
    cout<<s;
    s.DeQueue(e);
    s.DeQueue(e);
    cout<<s;

    cout<<"getSize(): "<<s.getSize()<<endl;

    cout<<boolalpha;
    cout<<"IsEmpty(): "<<s.IsEmpty()<<endl;
    cout<<"IsFull(): "<<s.IsFull()<<endl;
    cout<<noboolalpha;

    s.getFront(e);
    cout<<"getFront(): "<<e<<endl;

    SeqQueue<int> s1(s),s2;
    cout<<s1;
    s2=s;
    cout<<s2;

    system("pause");
    return 0;
}

測试结果例如以下:

front=0 rear=4
elements: 1 2 3 4
front=2 rear=4
elements: 3 4
getSize(): 2
IsEmpty(): false
IsFull(): false
getFront(): 3
front=2 rear=4
elements: 3 4
front=2 rear=4
elements: 3 4
请按随意键继续. . .

注意事项:

1.该实现是正对动态数组存储的循环队列,在逻辑上构成了一个环。

2.rear指向实际队尾位置的下一个位置,front指向的是真正的对头元素所在的位置。

3.初始化时rear=front=0

4.推断空对:front=rear

5.推断满:(rear+1)%maxSize=front。

让rear指向front的前一个位置就觉得队列已满,所以最多仅仅能存储maxSize-1个元素。这是为了和队列空的推断相差别。

6.对头指正进1:front=(front+1)%maxSize

7.队尾指针进1:rear=(rear+1)% maxSize

时间: 2024-10-26 15:01:37

[数据结构]队列之顺序队列的类模板实现的相关文章

[数据结构]栈之顺序栈的类模板实现

栈的数组实现形式,采用动态分配数组,不够时可以调整栈的大小. Stack.h文件:主要定义栈的抽象基类,提供公共的接口函数. #ifndef STACK #define STACK //栈的抽象基类 template<class T> class Stack { public: Stack(){} ~Stack(){} virtual void Push(const T& x)=0; virtual bool Pop(T& x)=0; virtual bool getTop(T

数据结构--队列实现(顺序队列和链队列)与C++模板

数据结构--队列实现(顺序队列和链队列)与C++模板 一.顺序队列 队列的顺序存储结构称为顺序队列,顺序队列实际上是运算受限的顺序表. ①和顺序表一样,顺序队列用一个向量空间来存放当前队列中的元素. ②由于队列的队头和队尾的位置是变化的,设置两个指针front和rear分别指示队头元素和队尾元素在向量空间中的位置,它们的初值在队列初始化时均应置为0. 注意: ①当头尾指针相等时,队列为空. ②在非空队列里,队头指针始终指向队头元素,尾指针始终指向队尾元素的下一位置.(所以以下循环顺序队列中当队尾

11. C#数据结构与算法 -- 顺序队列

理论基础: 队列(Queue)是插入操作限定在表的尾部而其它操作限定在表的头部进行的线性表.把进行插入操作的表尾称为队尾(Rear),把进行其它操作的头部称为队头(Front). 对列的操作是按照先进先出(First In First Out)或后进后出( Last In Last Out)的原则进行的,因此,队列又称为FIFO表或LILO表. 与栈一样,队列的运算是定义在逻辑结构层次上的,而运算的具体实现是建立在物理存储结构层次上的.因此,把队列的操作作为逻辑结构的一部分,每个操作的具体实现只

队列:顺序队列和循环队列

和栈的先进后出不同,队列的形式是先进先出,队列的想法来自于生活中排队的策略, 顾客在付款结账的时候,按照到来的先后顺序排队结账.先来的顾客先结账,后来的顾客后结账. 队列有两种实现形式:1 顺序表实现 2 循环顺序表 首先来看下顺序表的实现,在python中,队列的实现用list来写十分的方便.实现方式如下: class line_queue(): def __init__(self): self._elem=[] def push(self,elem): self._elem.append(e

[数据结构]线性表之顺序表的类模板实现

LinearList.h抽象基类: #ifndef LINEARLIST #define LINEARLIST //线性表的抽象基类 template<class T> class LinearList { public: LinearList(){};//如果派生类不需要向基类构造函数传递参数,则就会调用基类默认构造函数,所以,要么不写,要么就自己写默认构造函数. ~LinearList(){};//派生类也会调用基类的析构函数. virtual int Size()const=0; vir

顺序表 C++ 类模板实现

顺序表的C++语言描述 基本运算的算法--置空表.求表的长度.取结点.定位运算.插入运算.删除运算.建立顺序表.输出顺序表 #include <iostream>using namespace std;#define OK 1#define ERROR 0template <class T>class Linklist{public: Linklist() { } int initLinklist(Linklist < T > & L,int maxlistsi

数据结构-循环顺序队列&amp;链队列

队列接口实现: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _003_队列 { interface IQueue<T> { int Count { get; } int GetLength(); bool IsEmpty(); void Clear(); void Enqueue(T it

C++循环顺序队列

顾名思义:采用顺序结构存放的队列称为顺序队列 循环顺序队列可以避免队列的假溢出现象的发生.如下图示,循环队列的几种特殊情况. 学习完顺序循环队列个人感觉应该注意的事项: front.rear只是表示在base[i]这个顺序表中的索引值,而不是内存的绝对地址,这样也才在后面的循环的时候处理起来比较方便 队列循环的关键 front=(front+1)%queueSize; 下面是个人的循环队列操作工程文件: //////////////////////////////////////////////

顺序队列和链式队列的实现

队列是一种常用的数据结构,它跟栈一样,操作都受到限制,队列只允许从一端进数据,另一端出数据.队列跟栈不同,栈是一种"后进先出"的模式,而队列是一种"先进先出"的操作模式.就好比日常排队一样,先排队的先出,后排队的后出.例如,进入队列的顺序是1,2,3,4,5则出队列的顺序是1,2,3,4,5(只考虑一次性出列的情况). 队列也分顺序队列和链式队列,跟顺序栈和链表栈一样,顺序队列同样是基于数组实现,链式队列则是基于链表实现. 顺序队列: //顺序队列 #include