对于StaticQueue,当数据元素为类类型时,StaticQueue的对象在创建时,会多次调用元素类型的构造函数,影响效率。我们需要链式队列来解决这个问题。
LinkQueue.h:
#ifndef LINKQUEUE_H #define LINKQUEUE_H #include "Queue.h" #include "LinkList.h" #include "Exception.h" namespace LemonLib { template <typename T> class LinkQueue : public Queue<T> { protected: LinkList<T> m_list; public: void add(const T &e) { m_list.insert(e); } void remove() { if (m_list.length() > 0) { m_list.remove(0); } else { THROW_EXCEPTION(InvalidOperationException, "remove error, link queue is empty"); } } T front() const { if (m_list.length() > 0) { return m_list.get(0); } else { THROW_EXCEPTION(InvalidOperationException, "front error, link queue is empty"); } } void clear() { m_list.clear(); } int size() const { return m_list.length(); } }; } #endif // LINKQUEUE_H我们可以发现使用LinkList实现链式队列,在入队时时间复杂度为O(n),这显然是可以优化的。
类的继承关系图如下:
LinkQueue.h:
#ifndef LINKQUEUE_H #define LINKQUEUE_H #include "Queue.h" #include "LinuxList.h" #include "Exception.h" namespace LemonLib { template <typename T> class LinkQueue : public Queue<T> { protected: struct Node : public Object { list_head head; T e; }; list_head m_header; int m_length; public: LinkQueue() { m_length = 0; INIT_LIST_HEAD(&m_header); } void add(const T &e) { Node* node = new Node(); if (node != NULL) { node->e = e; list_add_tail(&node->head, &m_header); m_length++; } else { THROW_EXCEPTION(NoEnoughMemoryException, "linkqueue add error, no enough memory"); } } void remove() { 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, "remove error, link queue is empty"); } } T front() const { if (m_length > 0) { return list_entry(m_header.next, Node, head)->e; } else { THROW_EXCEPTION(InvalidOperationException, "front error, link queue is empty"); } } void clear() { while (m_length > 0) { remove(); } } int size() const { return m_length; } // 不要忘记提供析构函数 ~LinkQueue() { clear(); } }; } #endif // LINKQUEUE_H