鏈隊

隊列用鏈表來表示時,須要用兩個變量來記錄隊列兩端的變化:theFront,theBack.node

根據連接方向的不一樣,鏈隊有兩種連接方式(其實就是鏈表的頭插入節點和尾插入節點,頭刪除節點和尾刪除節點)。ios

鏈表隊列兩種記錄數據的方式

插如操做時,兩種方式都是同樣的;刪除元素的時候,從頭到尾的方式更便於操做。函數

鏈隊的初始值爲queueFront=queueBack=NULL,當且僅當隊列爲空時,queueFront=NULL測試

下面是隊列鏈表的兩種描述,對比可看出,從頭至尾連接方式在刪除操做時更加方便:this

插入和刪除

下面的代碼的具體實現:spa

/*
 * 測試函數
 * linkedQueue.cpp
*/
#include<iostream>
#include"linkedqueue.h"
#include"myexceptions.h"

int main(void)
{
    linkedQueue<int> q;

    q.push(1);
    cout<<"Queue back is "<<q.back()<<endl;
    q.push(2);
    cout<<"Queue back is "<<q.back()<<endl;
    q.push(3);
    cout<<"Queue back is "<<q.back()<<endl;
    q.push(4);
    cout<<"Queue back is "<<q.back()<<endl;


    cout<<"Queue should be 1234,front to back"<<endl;

    if(q.empty())
        cout<<"The queue is empty"<<endl;
    else
        cout <<"The queue is not empty"<<endl;

    cout<<"The queue size is "<<q.size()<<endl;

    while(!q.empty())
    {
        cout <<"Queue front is "<<q.front()<<endl;
        q.pop();
        cout <<"Popped front element"<<endl;
    }

    try{q.pop();}
    catch(queueEmpty message)
    {
        cout <<"Last pop failed"<<endl;
        message.outputMessage();
    }
    return 0;
}
/*
 * 鏈表的節點類,定義了節點該有的基本屬性
 * chainNode.h
*/
#ifndef CHAINNODE_H
#define CHAINNODE_H

template<class T>
struct chainNode
{
    T element;//節點元素
    chainNode<T> *next;//指向下一個元素的指針

    //所需函數
    chainNode() {}

    //節點中元素的複製
    chainNode(const T& element)
    {
        this->element = element;
    }

    //節點複製
    chainNode(const T &element,chainNode<T> *next)
    {
        this->element = element;
        this->next = next;
    }
};


#endif // CHAINNODE_H
/*
 * 隊列抽象類定義
 * queue.h
*/
#ifndef QUEUE_H
#define QUEUE_H

using namespace std;

template<class T>
class queue
{
   public:
    virtual ~queue(){}
    virtual bool empty() const = 0;//隊列爲空判斷
    virtual int size() const = 0;//隊列元素個數
    virtual T& front() = 0;//隊首引用
    virtual T& back()  = 0;//隊尾引用
    virtual void pop() = 0;//出隊
    virtual void push(const T& theElement) = 0;//入隊
};

#endif // QUEUE_H
/*
 *鏈隊的具體實現類
 * linkedQueue.h
 *
 *
*/

#ifndef LINKEDQUEUE_H
#define LINKEDQUEUE_H

#include"queue.h"
#include"myexceptions.h"
#include"chainnode.h"
#include<sstream>

using namespace std;

template<class T>
class linkedQueue : public queue<T>
{
public:
    //鏈隊初始化,將隊列置空
    linkedQueue(int initialCapacity = 10)
    {
        queueFront = NULL;
        queueSize = 0;
    }

    //析構函數,釋放隊列元素,將隊列置空
    ~linkedQueue()
    {
        //跟出隊類似的操做,不過是要將隊列中的元素一個一個的釋放掉
        while (queueFront != NULL)
        {
            chainNode<T>* nextNode = queueFront->next;
            delete queueFront;
            queueFront = nextNode;
        }
    }

    bool empty() const
    {
        return queueSize == 0;
    }

    int size() const
    {
        return queueSize;
    }

    //返回隊首元素
    T& front()
    {
        if(queueSize == 0)
            throw queueEmpty();
        return queueFront->element;
    }

    //返回隊尾元素
    T& back()
    {
        if(queueSize == 0)
            throw  queueEmpty();
        return queueBack->element;
    }

    //出隊操做
    void pop()
    {
        if(queueFront == NULL)
            throw queueEmpty();

        chainNode<T>* nextNode = queueFront->next;
         delete queueFront;
        queueFront = nextNode;
        queueSize--;
    }

    //入隊操做
    void push(const T& theElement)
    {
        chainNode<T>* newNode = new chainNode<T>(theElement,NULL);
        if(queueSize == 0)
            queueFront = newNode;
        else
            queueBack->next = newNode;

        queueBack = newNode;//不管隊列是否爲空,都有這一步操做

        queueSize++;
    }


private:
    chainNode<T> *queueFront;
    chainNode<T> *queueBack;
    int queueSize;
};


#endif // LINKEDQUEUE_H
/*
 * 異常處理類
 * myExceptions.h
*/
#ifndef MYEXCEPTIONS_H
#define MYEXCEPTIONS_H
#include<string>

using namespace std;

//template<class T>
class queueEmpty
{
  public:
    queueEmpty(string theMessage =
            "Invalid operation on empty queue")
    {
        message = theMessage;
    }
    void outputMessage()
    {
        cout << message <<endl;
    }
private:
    string message;
};


#endif // MYEXCEPTIONS_H
相關文章
相關標籤/搜索