队列

队列:队列是一种仅仅能在线性表两端操作的数据结构。

   队列头部(front):取出数据的一端。

   队列尾部(rear): 插入数据的一端。

队列的特性:先进先出。

继承关系:

 

Queue.h

/*
*    Queue: 队列接口
*    成员函数:
*        add()        在队尾(rear)插入一个元素。进队列
*        remove()    删除队列头部(front)的一个元素。出队列。
*        front()        返回队列头部的元素
*        clear()        清空整个队列
*        length()    返回队列元素的个数
*/

#ifndef QUEUE_H
#define QUEUE_H

#include"TopClass.h"

namespace DSL
{
    template <typename T>
    class Queue : public TopClass
    {
    public:
        virtual void add(const T& obj) = 0;        
        virtual void remove() = 0;
        virtual T front() const = 0;
        virtual void clear() = 0;
        virtual int length() const = 0;
    };
}
#endif
View Code

 

 

队列的顺序存储的实现:使用循环数组作为存储空间。首元素为零,最大尾元素为容量减一。

StaticQueue.h

/*
*    StaticQueue:    静态循环数组实现队列
*    成员变量:
*            m_space[]    队列存储空间,T是数组成员变量类型,N是数组长度
*            m_front        队头标识符
*            m_rear        队尾标识符,指向真实队尾的下一个元素,方便于判断队列是否满或空
*            m_length    队列实时长度
*    成员函数:
*            StaticQueue()    初始化成员变量
*            add()            插入元素到队尾
*            remove()        删除队头元素
*            front()            返回队头元素
*            clear()            清空成员变量
*            length()        返回实时队列长度
*            ~StaticQueue()    
*/

#ifndef STATICQUEUE_H
#define STATICQUEUE_H

#include"Queue.h"
#include"Exception.h"

namespace DSL
{
    template <typename T, int N>
    class StaticQueue : public Queue<T>
    {
    protected:
        T m_space[N];
        int m_front;
        int m_rear;
        int m_length;
    public:
        StaticQueue()
        {
            m_front = 0;
            m_rear = 0;
            m_length = 0;
        }

        void add(const T& obj)
        {
            if(m_length < N)
            {
                m_space[m_rear] = obj;
                m_rear = (m_rear + 1) % N;
                m_length++;
            }
            else
            {
                THROW_EXCEPTION(InvalidOperationException,"no space in current queue!");
            }
        }
        
        void remove()
        {
            if(m_length > 0)
            {
                m_front = (m_front + 1) % N;
                m_length--;
            }
            else
            {
                THROW_EXCEPTION(InvalidOperationException,"no element to remove from the queue!");
            }
        }

        T front() const
        {
            if(m_length > 0 && m_length <= N)
            {
                return m_space[m_front];
            }
            else
            {
                THROW_EXCEPTION(InvalidOperationException,"no element to get from the queue!");
            }
        }

        int length() const
        {
            return m_length;
        }

        void clear()
        {
            m_length = 0;
            m_front = 0;
            m_rear = 0;
        }

        ~StaticQueue()    
        {
            clear();
        }
        
        
    };
}

#endif
/* Test 
int main(void)
{
    StaticQueue<int,5> queue;
    for(int i = 0; i < 5; i++)
    {
        queue.add(i);
    }

    while(queue.length() > 0)
    {
        cout << queue.front() << endl;
        queue.remove();
    }
    return 0;
} 

*/
View Code

 

缺点:数组元素为类类型是,创建StaticQueue对象时,会多次调用元素类型的构造函数。

 

队列的链式存储的实现:组合单链表,继承队列。链表头是队列头,链表尾是队列尾。链表头部出数据,链表尾部入数据。

继承关系图:

LinkListqueue.h

 

缺点:插入时间复杂度为 O(n)

 

队列的双向循环链表的实现:采用Linux内核链表。

继承关系图:

 LinkListQueue.h

/*
*    LinkListQueue:    单链表队列
*    成员变量:
*            LinkList<T> m_LinkList:    组合使用单链表类来实现队列
*    成员函数:
*            LinkListQueue        
*            add()                在队列尾部添加数据(单链表尾部)
*            remove()            在队列头部取出数据(单链表头部)
*            front()                取出队列头部数据(单链表头部)
*            clear()                清除所有数据(清空单链表)
*            length()            返回队列长度(返回单链表长度)
*            ~LinkListQueue()    清空队列(清空单链表)
*/

#ifndef LINKLISTQUEUE_H
#define LINKLISTQUEUE_H

#include"LinkList.h"
#include"Queue.h"

namespace DSL
{
    template <typename T>
    class LinkListQueue : public Queue<T>
    {
    protected:
        LinkList<T> m_LinkList;
    public:
        LinkListQueue()
        {

        }

        void add(const T& obj)
        {
            m_LinkList.insert(obj);
        }

        void remove()
        {
            if(m_LinkList.length() > 0)
            {
                m_LinkList.remove(0);
            }
            else
            {
                THROW_EXCEPTION(InvalidOperationException,"error: no element to remove!");
            }
        }

        T front() const
        {
            if(m_LinkList.length() > 0)
            {
                m_LinkList.get(0);
            }
            else
            {
                THROW_EXCEPTION(InvalidOperationException,"error: no element to get!");
            }
        }

        int length() const
        {
            return m_LinkList.length();
        }

        void clear()
        {
            m_LinkList.clean();
        }

        ~LinkListQueue()
        {
            clear();
        }

    };
}

#endif
View Code

 

posted @ 2019-08-07 08:31  张不源  Views(146)  Comments(0Edit  收藏  举报