棧和隊列的C++實現

 線性表中,先進先出的叫隊列,先進後出的叫棧。隊列常用於BFS,而在函數遞歸層數過高時,需要手動實現遞歸過程,這時候便需要寫一個“手動棧”。

         有時候,我們會有大量數據頻繁出入隊列,但同時存在其內的元素卻不多,此時需要寫“循環隊列”。其代碼並不難,但裏面下標遞增的語句值得斟酌一下。

k=(k+1)%maxn;

         這句話用到了取模運算%,是非常浪費時間的。若能避免使用%,則可以大大提高代碼運行速度。我做了一個測試,把下面五種語句寫法分別運行5×10^8次,在我的機器上用codeblocks10.05各運行5次,取平均數,時間如下所示:

i=(i==maxn-1)?0:(i+1);          // 用時1.582s
if(i==maxn-1) i=0; else ++i;    // 用時1.588s
++i; if(i==maxn) i=0;           // 用時1.605s
++i; i=(i==maxn)?0:i;           // 用時2.040s
i=(i+1)%maxn;                   // 用時4.538s

考慮到codeblocks本身的誤差,我單單除去這條語句,將代碼其餘部分在codeblocks下的運行,依舊5次取平均,時間爲:0.015s。

  因此,算入誤差可以發現,前兩條語句最快,第三條也不錯,第四條較慢,最後一條用了3倍的時間。故而我的代碼中採用了第一行的寫法,建議大家儘量採用前三行的寫法。

下面給出代碼:

 // 假設儲存的信息類型是int
 
 // 棧
 class Stack
 {
     static const int maxn = 10000;
     int S[maxn],L;
 public:
     Stack(): L(0) {}
     void in(int x) { S[L++]=x; }
     int out() { return S[--L]; }
     int size() { return L; }
 };
 
 // 隊列
 class Queue
 {
     static const int maxn = 10000;
     int Q[maxn],i,j;
 public:
     Queue(): i(0), j(0) {}
     void in(int x) { Q[j++]=x; }
     int out() { return Q[i++]; }
     int size() { return j-i; }
 };
 
 // 循環隊列
 class CycleQueue
 {
     static const int maxn = 10000;
     int Q[maxn],i,j;
     void add(int &k) { k=(k==maxn-1)?0:(k+1); }
 public:
     CycleQueue(): i(0), j(0) {}
     void in(int x) { Q[j]=x; add(j); }
     int out() { int x=Q[i]; add(i); return x; }
     int size() { return (j>i)?(j-i):(j+maxn-i); } // 此處提醒,循環隊列元素個數應在0~maxn-1之間,不可達到maxn
38 };

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章