deque c 學習記錄

2021-10-18 07:39:16 字數 2239 閱讀 8393

首先介紹下deque,deque是乙個雙向的佇列,也就是既可以從佇列的前面入隊,也可以從佇列的後面入隊,同樣可以從佇列的前面出隊,也可以從佇列的後面出隊。用圖表示就是

但是的deque的中資料的儲存方式卻不是順序儲存或者雙向鍊錶一樣的離散儲存而是下面的結構:

先別急,首先最中間的map和mapsize,上的是map並不是指這個結構是鍵值對的map,而是一種對映關係,因為裡面都是指標,指出去了,指向了在堆上的buffer,二buffer裡面才是真正元素存放的地方,這個map裡面的指標實際上是存放在乙個vector(順序表)裡面,當所有buffer裡面都裝滿了再要裝元素的時候就會來擴充這個vector,擴充到原來的兩倍,然後將以前vector裡面的內容拷貝到新的vector裡面,但是並不是拷貝到新的vector的起始位置,比如以前的vector的size是8,現在擴容到16,就會從新的vector的第四個位置開始拷貝,因為這個乙個雙端佇列所以前面和後面都要留位置,再看start和finish這兩個(iterator)迭代器,和其他容器一樣,容器都會維護start和finish兩個迭代器,迭代器的資料結構是四個指標,start迭代器中的cur指標指向的是deque這個雙端佇列的第乙個元素,start裡面的first指向的是第乙個元素所在的buffer的首位址,start裡面的last指向的是第乙個元素所在的buffer的尾位址,start裡面的node則是指向vector裡面的第乙個元素的位址,毫無疑問node是乙個二級指標,同理finish裡面的cur指向的是最後乙個buffer中最後乙個元素的下乙個元素的首位址,first則是最後乙個buffer的首位址,finish是最後乙個buffer的尾位址。這個整個deque的結構就清楚了,下面是具體的源**。

然後介紹一下deque的乙個函式

函式要傳入乙個iterator和乙個value,首先判斷如果這個傳進來的迭代器的cur是否和start,finish的cur指向相同的位置,如果是則執行對應的**如上,因為是雙端佇列,在首和尾上插入就很簡單,但是如果在隊伍中間插入呢?就會執行insert_aux函式如下,首先會判斷這個插入的位置離隊伍首端更近還是離隊伍的尾端更近,如果離首端更近就將插入點的元素往前面移然後查到空位上,反之則插到尾端。

接下來是的確模擬連續空間,連續空間的模擬當然少不了迭代器和操作符過載:

首先就是類似於陣列一樣的的中括號訪問的形式,但是裡面是並沒有訪問到真確的元素的,裡面應該是又跳到了迭代器的操作符過載函式裡面,應該是還會判斷是否越界,在哪個緩衝區裡面,然後back,size,empty函式裡面的被藍色標記出來的操作符很顯然被過載了的,因為在這裡很顯然會有一些想法,看下面:

*號操作符裡面去返回cur,也就是當前迭代器cur所指向的元素,而->又去呼叫星號操作符,返回了cur的位址,這是個很好的寫法,得記下,就是-操作符過載了,上一張上-號操作符是為了計算deque中的元素個數,所以分為三部分,分別是start和finish中完整buffer的數量,然後就是第乙個buffer和最後乙個buffer中元素的個數,因為第乙個和最後乙個buffer中可能未填滿。

然後後面的就是++操作符了,如果是vector裡面就很簡單了,因為是線性的,看第乙個++操作符過載,也就是前加加操作符過載了,需要判斷是否到了buffer的邊界,這裡注意乙個細節,先讓cur執行++操作,假設cur指向buffer的最後乙個元素++就會超過buffer所以last應該是指向buffer的尾端,當然如果cur指向buffer的最後乙個元素的話,再執行++操作就要移到下乙個緩衝區了。而在後加加裡面又去呼叫的前加加,好寫法。

後面還有幾個操作符過載有興趣的可以自己看看。

這篇文章是學習了侯捷老師的deque分析所寫,有錯誤希望指正

mysql學習記錄 MySQL學習記錄 2

in 子查詢 select from student where id in 1,2 not in 不在其中 select from student where id not in 1,2 is null 是空 select from student where age is null is not...

java學習記錄

陣列雖然是引用資料型別,但它不是類 所以數字中沒有length 方法 只有length屬性。string型別 是乙個類 jdk中已經封裝好的類,是個final類,你可以去查api 類就有屬性和方法但是 string類中沒有length屬性,只有length 方法 1。陣列雖然是引用資料型別,但它不是...

Linux 學習記錄

1.linux 拷貝隱藏檔案 進入當前需要拷貝的目錄,即源目錄 假如 source 拷貝到 centos5.3 cd source tar cf cd centos5.3 tar xvf 或者 cp r centos5.3 2.linux 下新增postgresql 使用者 進入 postgresq...