当数据元素为类类型,StaticQueue 的对象在建立时会屡次调用元素类型的构造函数,影响效率!node
文件:main.cppios
#include <iostream> #include "StaticQueue.h" using namespace std; using namespace DTLib; class Test : public Object { public: Test() { cout << "Test()" << endl; } ~Test() { cout << "~Test()" << endl; } }; int main() { StaticQueue<Test, 5> queue; cout << "queue.length() = " << queue.length() << endl; return 0; }
输出:编程
Test() Test() Test() Test() Test() queue.length() = 0 ~Test() ~Test() ~Test() ~Test() ~Test()
- 类模板,抽象父类 Queue 的直接子类
- 在内部使用链式结构实现元素的存储
- 只在链表的头部和尾部进行操做
文件:LinkQueue.hide
#ifndef LINKQUEUE_H #define LINKQUEUE_H #include "Queue.h" #include "LinkList.h" #include "Exception.h" namespace DTLib { template <typename T> class LinkQueue : public Queue<T> { public: LinkQueue() = default; void add(const T &e) override // O(n) { m_list.insert(e); } void remove() override // O(1) { if (m_list.length() > 0) { m_list.remove(0); } else { THROW_EXCEPTION(InvalidOpertionExcetion, "No element in current StaticQueue ..."); } } T front() const override // O(1) { if (m_list.length() > 0) { return m_list.get(0); } else { THROW_EXCEPTION(InvalidOpertionExcetion, "No element in current StaticQueue ..."); } } void clear() override // O(n) { m_list.clear(); } int length() const override // O(1) { return m_list.length(); } ~LinkQueue() // O(n) { clear(); } protected: LinkList<T> m_list; }; } #endif // LINKQUEUE_H
文件:main.cpp函数
#include <iostream> #include "LinkQueue.h" using namespace std; using namespace DTLib; class Test : public Object { public: Test() { cout << "Test()" << endl; } ~Test() { cout << "~Test()" << endl; } }; int main() { LinkQueue<Test> queue_t; cout << "-----" << endl; LinkQueue<int> queue; for (int i=0; i<5; ++i) { queue.add(i); } while (queue.length() > 0) { cout << queue.front() << endl; queue.remove(); } return 0; }
输出:优化
----- 0 1 2 3 4
问题:使用 LinkList 类实现链表式队列是否合适?是否有更好的方案?
void add(const T &e) override // O(n) { m_list.insert(e); }
每次插入新元素,都须要遍历整个链表到尾部!!spa
文件: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> { public: LinkQueue() { m_length = 0; INIT_LIST_HEAD(&m_header); } void add(const T &e) override // O(1) { Node *node = new Node; if (node != nullptr) { node->value = e; list_add_tail(&node->head, &m_header); ++m_length; } else { THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory to add element ..."); } } void remove() override // 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(InvalidOpertionExcetion, "No element in current LinkQueue ..."); } } T front() const override // O(1) { if (m_length > 0) { return list_entry(m_header.next, Node, head)->value; } else { THROW_EXCEPTION(InvalidOpertionExcetion, "No element in current LinkQueue ..."); } } void clear() override // O(n) { while (m_length > 0) { remove(); } } int length() const override // O(1) { return m_length; } ~LinkQueue() // O(n) { clear(); } protected: struct Node : public Object { list_head head; T value; }; list_head m_header; int m_length; }; } #endif // LINKQUEUE_H
文件:main.cppcode
#include <iostream> #include "LinkQueue.h" using namespace std; using namespace DTLib; class Test : public Object { public: Test() { cout << "Test()" << endl; } ~Test() { cout << "~Test()" << endl; } }; int main() { LinkQueue<Test> queue_t; cout << "-----" << endl; LinkQueue<int> queue; for (int i=0; i<5; ++i) { queue.add(i); } while (queue.length() > 0) { cout << queue.front() << endl; queue.remove(); } return 0; }
输出:对象
----- 0 1 2 3 4
- SaticQueue 在初始化时可能屡次调用元素类型的构造函数
- LinkList 的组合使用实现了队列的功能,可是不够高效
- LinkQueue 的最终实现组合使用了 Linux 内核链表
- LinkQueue 中入队和出队操做能够在常量时间内完成
以上内容整理于狄泰软件学院系列课程,请你们保护原创!