[C++][數據結構]隊列(queue)的實現


對於隊列的定義,前人之述備矣。

隊列的實現方法與棧非常相似。我直接在我實現的那個棧的代碼上加了一點東西,全局替換了一些標識符,就實現了這個隊列。

我實現的是一個queue<value>容器類,支持push,pop,top,size,empty,clear和copy construction操作。

主要的實現思路是,先寫出幾個支持基本操作的類_queue_impl,然后再寫一個包裝類queue,包裝基本操作,再實現size,copy struction,top,clear和拋出異常的功能。這樣做(pImpl)的好處不言而喻。

我實現的copy structurion其實是用的一個包裝了的友元函數_queue_copy(dst, src),因為這樣可以直接訪問底部成員並進行復制,比使用用戶接口,先一個一個pop,再一個一個push,快多了。

代碼使用C++11標准。如果有不對的地方,歡迎指出。

在Win7 mingw32 gcc4.7下編譯並測試通過。測試內容非常簡單,所以可能會有一些沒測試出來的問題。

以下是實現

  1 #pragma once
  2 #include <cstddef>
  3 #include <stdexcept>
  4 
  5 namespace jt {
  6 
  7 template <class value>
  8 class queue {
  9   template <class v>
 10   friend void _queue_copy(queue<v>& dst, const queue<v>& src);
 11 
 12 private:
 13   struct _queue_impl;
 14   _queue_impl *_impl = nullptr;
 15   size_t _siz;
 16 
 17   void _init_empty() {
 18     _siz = 0;
 19     if (_impl) delete _impl;
 20     _impl = new _queue_impl;
 21   }
 22 
 23   void _destory() { _siz = 0; delete _impl; }
 24 
 25 public:
 26   queue() { _init_empty(); }
 27   queue(const queue<value> &o) { _queue_copy(*this, o); }
 28   ~queue() { _destory(); }
 29 
 30   void clear() { _init_empty(); }
 31   void push(const value &val) { _impl->push(val); ++_siz; }
 32   size_t size() const { return _siz; }
 33 
 34   value pop() {
 35     if (_siz == 0)
 36       throw std::out_of_range("jt::queue::pop() - Empty queue");
 37     --_siz; return _impl->pop();
 38   }
 39 
 40   bool empty() const { return _siz == 0; }
 41 
 42   value front() const {
 43     if (_siz == 0)
 44       throw std::out_of_range("jt::queue::front() - Empty queue");
 45     return _impl->f->val;
 46   }
 47 
 48   value back() const {
 49     if (_siz == 0)
 50       throw std::out_of_range("jt::queue::back() - Empty queue");
 51     return _impl->b->val;
 52   }
 53 };
 54 
 55 template <class value>
 56 static void _queue_copy(queue<value> &dst, const queue<value> &src) {
 57   dst._init_empty();
 58   auto **dn = &dst._impl->f; // dest node
 59 
 60   for (auto *s = src._impl->f; s; s = s->next) {
 61     *dn = new typename queue<value>::_queue_impl::node;
 62     (*dn)->val = s->val;
 63     dst._impl->b = *dn;
 64     dn = &(*dn)->next;
 65   }
 66 
 67   dst._siz = src._siz;
 68 }
 69 
 70 template <class value>
 71 struct queue<value>::_queue_impl {
 72   struct node {
 73     value val;
 74     node *next = nullptr;
 75   } *f = nullptr, // front
 76     *b;           // back
 77 
 78   ~_queue_impl() {
 79     while (f) {
 80       auto *tmp = f->next;
 81       delete f;
 82       f = tmp;
 83     }
 84   }
 85 
 86   void push(const value& val) {
 87     node *t = new node;
 88     t->val = val;
 89 
 90     if (f) b->next = t;
 91     else f = t; // if empty, set front
 92 
 93     b = t;
 94   }
 95 
 96   value pop() {
 97     value v = f->val;
 98 
 99     node *tmp = f->next;
100     delete f;
101     f = tmp;
102 
103     return v;
104   }
105 };
106 
107 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM