第37课 - 队列的概念及实现(下)

1、队列的概念及实现

        讨论中。。。

    


    队列的链式存储实现 



        链式队列的设计要点 

            -类模板,抽象父类Queue的直接子类 

            -在内部使用链式结构实现元素的存储 

            -只在链表的头部尾部进行操作 


        链式队列的设计要点 



2、编程实验

基于LinkList的队列     LinkQueue.h 
#ifndef STATICQUEUE_H
#define STATICQUEUE_H

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

namespace DTLib
{

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;
    }
    int capacity() const    //O(1)
    {
        return N;
    }
    void add(const T& e)    //O(1)
    {
        if(m_length < N)
        {
            m_space[m_rear] = e;
            m_rear = (m_rear + 1) % N;
            m_length++;
        }
        else
        {
            THROW_EXCEPTION(InvalidOperationException,"No space in current queue ...");
        }
    }
    void remove()   //O(1)
    {
        if(m_length > 0)
        {
            m_front = (m_front + 1) % N;
            m_length--;
        }
        else
        {
            THROW_EXCEPTION(InvalidOperationException,"No element in current queue ...");
        }
    }
    T front() const     //O(1)
    {
        if(m_length > 0)
        {
            return m_space[m_front];
        }
        else
        {
            THROW_EXCEPTION(InvalidOperationException,"No element in current queue ...");
        }
    }
    void clear()    //O(1)
    {
        m_front = 0;
        m_rear = 0;
        m_length = 0;
    }
    int length() const      //O(1)
    {
        return m_length;
    }
};
}
#endif // STATICQUEUE_H

                    


       问题 

                    使用Linklist类实现链式队列是否 

                    合适,是否有更好的方案?

                                会发现基于单链表的链式队列并不高效


        队列链式存储实现的优化



        链式队列的设计优化 



3、编程实验 

基于Linux内核链表的队列     LinkQueue.h 
#ifndef LINKQUEUE_H
#define LINKQUEUE_H

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

namespace DTLib
{

template < typename T >
class LinkQueue : public Queue<T>
{
protected:
    struct Node : public Object
    {
        list_head head;
        T value;
    };

    list_head m_header;
    int m_length;
public:
    LinkQueue()     //O(1)
    {
        m_length = 0;

        INIT_LIST_HEAD(&m_header);
    }
    void add(const T& e)    //O(1)
    {
        Node* node = new Node();

        if(node != NULL)
        {
            node->value = e;
            list_add_tail(&node->head,&m_header);   //O(1)
            m_length++;
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException,"No memory to add new element ...");
        }
    }
    void remove()   //O(1)
    {
        if(m_length > 0)
        {
            list_head* toDel = m_header.next;

            list_del(toDel);

            m_length--;

            delete list_entry(toDel,Node,head);
        }
        else
        {
            THROW_EXCEPTION(InvalidOperationException,"No element in current queue ...");
        }
    }
    T front() const     //O(1)
    {
        if(m_length > 0)
        {
            return list_entry(m_header.next,Node,head)->value;
        }
        else
        {
            THROW_EXCEPTION(InvalidOperationException,"No element in current queue ...");
        }
    }
    void clear()    //O(n)
    {
        while(m_length > 0)
        {
            remove();
        }
    }
    int length() const      //O(1)
    {
        return m_length;
    }
    ~LinkQueue()    //O(n)
    {
        clear();
    }
};
}
#endif // LINKQUEUE_H


4、小结 

            StaticQueue在初始化时可能多次调用元素类型的构造函数 

            LinkList的组合使用能够实现队列的功能,但是不够高效

            LinkQueue的最终实现组合使用了Linux内核链表 

            LinkQueue中入队和出队操作可以在常量时间内完成 



猜你喜欢

转载自blog.csdn.net/qq_39654127/article/details/80340659