基於環形緩衝區的deque實現方法

2021-07-23 20:40:22 字數 1830 閱讀 7535

眾所周知,c++ stl中有乙個叫做deque的容器,實現的是雙端佇列資料結構,這種佇列允許同時從佇列的首部和尾部插入和刪除資料。

然而在stl中這種資料結構是用」分段連續」的物理結構實現的(可以參考侯捷老師的《stl原始碼剖析》)。網上分析stl中這種容器的文章很多,如: (stl原始碼剖析——deque的實現原理和使用方法詳解)就分析得很清楚。

個人認為stl的這種實現方法略有畫蛇添足的嫌疑,不光增加了空間管理複雜度,而且使得iterator的隨機訪問變得低效(相對vector的iterator)。

侯捷老師在《stl原始碼剖析》第143頁也提到:「對deque進行的排序操作,為了最高效率,可將deque先完整複製到乙個vector身上,將vector排序後(利用stl sort演算法),再複製回deque。」只因deque的randon access iterator遠不如vector的原生指標來得高效。

雖然作者暫時沒弄明白為什麼需要對「佇列」做排序操作,即便如此,侯捷老師指出的copy-sort-copy思路,作者也是難苟同。

下面開始引出本文的主角——基於環形緩衝區的deque實現方法。

由於deque需要允許從佇列頭部插入和刪除資料,如果像vector那樣,為了在頭部增刪資料,每次都需要移動整個列表,顯然是無法忍受的。

然而,利用環形鍊錶思想,將vector的緩衝區看做是乙個環形,則可以完美的在像vector一樣連續的可增長的連續儲存空間內實現deque。

資料結構定義如下:

class

deque

其中[_myfirst, _mylast)記錄了當前緩衝區的位址範圍(即當前允許的最大佇列長度)。

_myhead和_mytail記錄了當前佇列的頭部和尾部的位置。

由於緩衝區是被看做是環形的,所以資料[_myhead,_mytail)可能有兩種情況:

1. _mytail >= _myhead, 佇列資料在[_myhead,_mytail)

2. _mytail < _myhead, 佇列資料在[_myhead, _mylast-1, _myfirst,_mytail)

下面來詳細講述deque的4個操作:

void push_front(const value_type &_val)

}void push_back(const value_type &_val)

}bool pop_front()

_destroy(_myhead);

_myhead=_next(_myhead);

return

true;

}bool pop_back()

_mytail = _prev(_mytail);

_destroy(_mytail);

return

true;

}bool empty() const

特別說明,當_myhead == _mytail的時候,表示隊列為空。

可以看到,從頭部push和pop的時候,實際只需要將_myhead- -和_myhead++

同理,從尾部push和pop的時候,只需要_mytail++和_mytail- -

當插入資料後,如果_myhead==_mytail,表示緩衝區已滿,需要重新申請更大(2倍)的緩衝區,並把佇列資料拷貝到新空間。

可以看到,以上**在跟vector類似的連續空間上簡單的實現了deque的所有關鍵操作,更讓人欣慰的是,iterator(如果需要)是跟vector一樣的原生指標,要在上面實現sort演算法將是相當高效的,絕對不需要的copy-sort-copy。

我將**放在了這裡:

歡迎有興趣的筒子學習研究,如有不當的地方,敬請批評指正。

環形緩衝區的實現

乙個簡單的環形緩衝區,沒有寫加解鎖的部分,用於多執行緒的話還是自己加吧.pragma once include stdio.h include stdlib.h include memory.h namespace linker ring bool put elementtype e else bo...

環形緩衝區

include include include include include define buffsize 1024 1024 define min x,y x y x y pthread mutex t lock pthread mutex initializer struct cycle b...

環形緩衝區

define print buf size 16 1024 static char g pcnetprintbuf 環形緩衝區的首位址 static int g ireadpos 0 環形緩衝區讀的位置 static int g iwritepos 0 環形緩衝區寫的位置 intinit 判斷環形緩...