[数据结构]队列之链式队列的类模板实现

链式队列是基于单链表的一种存储表示

队列的对头指针指向单链表的第一个节点,队尾指针指向单链表的最后一个节点,

退出一个元素 则删除对头指针的节点,添加元素则在队尾增加一个节点

使用条件:数据元素变动比较大的情况。不存在溢出的情况


队列的抽象基类:

#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>  
struct LinkNode //链表节点类  
{  
    T data;  
    LinkNode<T>* link;  
  
    LinkNode(LinkNode<T>* ptr=NULL):link(ptr){}  
    LinkNode(const T& item,LinkNode<T>* ptr=NULL):data(item),link(ptr){}  
}; 

template<class T>
class LinkedQueue:public Queue<T>
{
public:
    LinkedQueue():front(NULL),rear(NULL){}
    ~LinkedQueue(){makeEmpty();}
    LinkedQueue(const LinkedQueue<T>& rhs);
    LinkedQueue<T>& operator=(const LinkedQueue<T>& rhs);

    bool EnQueue(const T& x);
    bool DeQueue(T& x);
    bool getFront(T& x)const;
    bool IsEmpty()const{return (front==NULL)?true:false;}
    bool IsFull()const{return false;}//无意义,永远不可能满
    int getSize()const;

    void makeEmpty();
    friend ostream& operator<< <T>(ostream& os,const LinkedQueue<T>& rhs);

protected:
    LinkNode<T> *front,*rear;
};

template<class T>
void LinkedQueue<T>::makeEmpty()
{
    LinkNode<T>* p;
    while(front!=NULL){
        p=front;
        front=front->link;
        delete p;
    }
    rear=NULL;
}

template<class T>
bool LinkedQueue<T>::EnQueue(const T& x)
{
    if(front==NULL){
        front=rear=new LinkNode<T>(x);
        if(front==NULL||rear==NULL)//对new返回值的一个检测,安全机制
            return false;
    }
    else{
        rear->link=new LinkNode<T>(x);
        if(rear->link==NULL)
            return false;
        rear=rear->link;
    }
    return true;
}


template<class T>
bool LinkedQueue<T>::DeQueue(T& x)
{
    if(IsEmpty())
        return false;

    LinkNode<T>* p=front;
    if(front==rear){//只有一个节点的情况
        front=front->link;
        rear=NULL;
    }else{
        front=front->link;
    }
    x=p->data;
    delete p;
    return true;

}

template<class T>
bool LinkedQueue<T>::getFront(T& x)const
{
    if(IsEmpty())
        return false;
    x=front->data;
    return true;
}

template<class T>
int LinkedQueue<T>::getSize()const
{
    int k=0;
    LinkNode<T>* p=front;
    while(p!=NULL){
        ++k;
        p=p->link;
    }
    return k;
}

template<class T>
ostream& operator<<(ostream& os,const LinkedQueue<T>& rhs)
{
    os<<"size: "<<rhs.getSize()<<endl;
    LinkNode<T> *p=rhs.front;
    os<<"elements:";
    while(p!=NULL){
        os<<p->data<<" ";  
        p=p->link;
    }
    os<<endl;
    return os;

}

template<class T>
LinkedQueue<T>::LinkedQueue(const LinkedQueue<T>& rhs)
{
    LinkNode<T> *src=rhs.front;
    LinkNode<T> *dest=nullptr,*newNode=nullptr;
    front=nullptr;
    while(src!=NULL){
        newNode=new LinkNode<T>(src->data);
        if(front==nullptr){    //链表为无附加头结点的单链表,故比较特殊
            front=newNode;
            dest=newNode;
        }else{
            dest->link=newNode;
            dest=newNode;
        }
        src=src->link;
    }
    rear=dest;
}

template<class T>
LinkedQueue<T>& LinkedQueue<T>::operator=(const LinkedQueue<T>& rhs)
{
    makeEmpty();

    LinkNode<T> *src=rhs.front;
    LinkNode<T> *dest=nullptr,*newNode=nullptr;
    front=nullptr;
    while(src!=nullptr){
        newNode=new LinkNode<T>(src->data);
        if(front==NULL){
            front=newNode;
            dest=newNode;
        }else{
            dest->link=newNode;
            dest=newNode;
        }
        src=src->link;
    }
    rear=dest;
    return *this;
}

测试函数:


int main(int argc, char* argv[])
{
    LinkedQueue<int> s;
    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;
    
    cout<<endl;
    cout<<"copy and copy assignment"<<endl;
    LinkedQueue<int> s1(s),s2;
    cout<<s1;
    s2=s;
    cout<<s2;


    system("pause");
    return 0;
}

测试结果如下:


size: 4
elements:1 2 3 4
size: 2
elements:3 4
getSize(): 2
IsEmpty(): false
IsFull(): false
getFront(): 3

copy and copy assignment
size: 2
elements:3 4
size: 2
elements:3 4
请按任意键继续. . .


注意事项:

1.要对返回的指针值进行检测,比如用new时要对返回值进行检测,查看内存是否分配成功。这是随时随地的安全机制。

2.该实现所用的链表是没有附加头结点的单链表,所以拷贝构造函数和拷贝复制函数的编写要注意。

3.想清楚在写代码,否则漏洞很多。











  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值