zoukankan      html  css  js  c++  java
  • [数据结构]队列之链式队列的类模板实现

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

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

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

    使用条件:数据元素变动比較大的情况。

    不存在溢出的情况


    队列的抽象基类:

    #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.想清楚在写代码,否则漏洞非常多。











  • 相关阅读:
    使用SignalR实现即时通讯功能
    SignalR入门篇
    Mongodb关闭开源许可感想
    RaspberryPi学习教程系列4(串口通信篇)
    RaspberryPi学习教程系列3(编程实验篇-双色LED实验)
    RaspberryPi学习教程系列1(系统安装篇)
    RaspberryPi学习教程系列2(编程前准备篇)
    关于Entity Framework,园里有非常多误人子弟的`
    Java多线程1:使用多线程的几种方式以及对比
    Django编写RESTful API(六):ViewSets和Routers
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/6908139.html
Copyright © 2011-2022 走看看