LinkQueue
文章目錄
- 1 鏈?zhǔn)疥?duì)列的概念
- 1.1 隊(duì)列的鏈?zhǔn)酱鎯?shí)現(xiàn)
- 1.2 鏈?zhǔn)疥?duì)列的設(shè)計(jì)要點(diǎn)
- 2 使用LinkList實(shí)現(xiàn)鏈?zhǔn)疥?duì)列
- 2.1 繼承關(guān)系圖
- 2.2 代碼實(shí)現(xiàn)
- 3 使用LinuxList實(shí)現(xiàn)LinkQueue
- 3.1 隊(duì)列鏈?zhǔn)酱鎯?shí)現(xiàn)的優(yōu)化
- 3.2 代碼實(shí)現(xiàn)
- 4 小結(jié)
1 鏈?zhǔn)疥?duì)列的概念
對于StaticQueue,當(dāng)數(shù)據(jù)元素為類類型時,StaticQueue的對象在創(chuàng)建時,會多次調(diào)用元素類型的構(gòu)造函數(shù),影響效率。我們需要鏈?zhǔn)疥?duì)列來解決這個問題。
1.1 隊(duì)列的鏈?zhǔn)酱鎯?shí)現(xiàn)
1.2 鏈?zhǔn)疥?duì)列的設(shè)計(jì)要點(diǎn)
- 類模板,抽象父類Queue的直接子類。
- 在內(nèi)部使用鏈?zhǔn)浇Y(jié)構(gòu)實(shí)現(xiàn)元素的存儲。
- 只在鏈表的頭部和尾部進(jìn)行操作。
2 使用LinkList實(shí)現(xiàn)鏈?zhǔn)疥?duì)列
2.1 繼承關(guān)系圖
2.2 代碼實(shí)現(xiàn)
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_H3 使用LinuxList實(shí)現(xiàn)LinkQueue
我們可以發(fā)現(xiàn)使用LinkList實(shí)現(xiàn)鏈?zhǔn)疥?duì)列,在入隊(duì)時時間復(fù)雜度為O(n),這顯然是可以優(yōu)化的。
3.1 隊(duì)列鏈?zhǔn)酱鎯?shí)現(xiàn)的優(yōu)化
類的繼承關(guān)系圖如下:
3.2 代碼實(shí)現(xià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;}// 不要忘記提供析構(gòu)函數(shù)~LinkQueue(){clear();} }; }#endif // LINKQUEUE_H4 小結(jié)
- StaticQueue在初始化時可能多次調(diào)用元素類型的構(gòu)造函數(shù)。
- LinkList的組合使用能夠?qū)崿F(xiàn)隊(duì)列的功能,但是不夠高效。
- LinkQueue的最終實(shí)現(xiàn)組合使用了Linux內(nèi)核鏈表。
- LinkQueue中入隊(duì)和出隊(duì)操作可以在常量時間內(nèi)完成。
總結(jié)
- 上一篇: StaticQueue
- 下一篇: 怎么关闭U盘扫描并修复功能 关闭U盘扫描