欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++ deque/queue/stack的底層原理解析

 更新時間:2023年07月21日 16:09:54   作者:lliuhao--  
這篇文章主要介紹了C++ deque/queue/stack的底層原理解析,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

deque容器的存儲結構

和 vector 容器采用連續(xù)的線性空間不同,deque 容器存儲數(shù)據的空間是由一段一段等長的連續(xù)空間構成,各段空間之間并不一定是連續(xù)的,可以位于在內存的不同區(qū)域。

deque采用一塊所謂的map數(shù)組(注意,不是STL的map容器)作為主控。這里所謂map是一小塊連續(xù)空間(類似于vector),其中每個元素(此處稱為一個節(jié)點,node)都是指針,指向另一段(較大的)連續(xù)線性空間,稱為緩沖區(qū)。緩沖區(qū)才是deque的儲存空間主體。SGI STL 允許我們指定緩沖區(qū)大小,默認值0表示將使用512 bytes 緩沖區(qū)。

通過建立 map 數(shù)組,deque 容器申請的這些分段的連續(xù)空間就能實現(xiàn)“整體連續(xù)”的效果。換句話說,當 deque 容器需要在頭部或尾部增加存儲空間時,它會申請一段新的連續(xù)空間,同時在 map 數(shù)組的開頭或結尾添加指向該空間的指針,由此該空間就串接到了 deque 容器的頭部或尾部。

如果 map 數(shù)組滿了怎么辦?很簡單,再申請一塊更大的連續(xù)空間供 map 數(shù)組使用,將原有數(shù)據(很多指針)拷貝到新的 map 數(shù)組中,然后釋放舊的空間。

deque 容器的分段存儲結構,提高了在序列兩端添加或刪除元素的效率,但也使該容器迭代器的底層實現(xiàn)變得更復雜。

deque容器迭代器的底層實現(xiàn)

由于 deque 容器底層將序列中的元素分別存儲到了不同段的連續(xù)空間中,因此要想實現(xiàn)迭代器的功能,必須先解決如下 2 個問題:

  • 迭代器在遍歷 deque 容器時,必須能夠確認各個連續(xù)空間在 map 數(shù)組中的位置;
  • 迭代器在遍歷某個具體的連續(xù)空間時,必須能夠判斷自己是否已經處于空間的邊緣位置。如果是,則一旦前進或者后退,就需要跳躍到上一個或者下一個連續(xù)空間中。

為了實現(xiàn)遍歷 deque 容器的功能,deque 迭代器定義了如下的結構:

template<class T,...>
struct __deque_iterator{
    ...
    T* cur;
    T* first;
    T* last;
    map_pointer node;//map_pointer 等價于 T**
}

可以看到,迭代器內部包含 4 個指針,它們各自的作用為:

  • cur:指向當前正在遍歷的元素;
  • first:指向當前連續(xù)空間的首地址;
  • last:指向當前連續(xù)空間的末尾地址;
  • node:它是一個二級指針,用于指向 map 數(shù)組中存儲的指向當前連續(xù)空間的指針。

借助這 4 個指針,deque 迭代器對隨機訪問迭代器支持的各種運算符進行了重載,能夠對 deque 分段連續(xù)空間中存儲的元素進行遍歷。例如:

//當?shù)魈幱诋斍斑B續(xù)空間邊緣的位置時,如果繼續(xù)遍歷,就需要跳躍到其它的連續(xù)空間中,該函數(shù)可用來實現(xiàn)此功能
void set_node(map_pointer new_node){
    node = new_node;//記錄新的連續(xù)空間在 map 數(shù)組中的位置
    first = *new_node; //更新 first 指針
    //更新 last 指針,difference_type(buffer_size())表示每段連續(xù)空間的長度
    last = first + difference_type(buffer_size());
}
//重載 * 運算符
reference operator*() const{return *cur;}
pointer operator->() const{return &(operator *());}
//重載前置 ++ 運算符
self & operator++(){
    ++cur;
    //處理 cur 處于連續(xù)空間邊緣的特殊情況
    if(cur == last){
        //調用該函數(shù),將迭代器跳躍到下一個連續(xù)空間中
        set_node(node+1);
        //對 cur 重新賦值
        cur = first;
    }
    return *this;
}
//重置前置 -- 運算符
self& operator--(){
    //如果 cur 位于連續(xù)空間邊緣,則先將迭代器跳躍到前一個連續(xù)空間中
    if(cur == first){
        set_node(node-1);
        cur == last;
    }
    --cur;
    return *this;
}

deque容器的底層實現(xiàn)

了解了 deque 容器底層存儲序列的結構,以及 deque 容器迭代器的內部結構之后,接下來看看 deque 容器究竟是如何實現(xiàn)的。

deque 容器除了維護先前講過的 map 數(shù)組,還需要維護 start、finish 這 2 個 deque 迭代器。以下為 deque 容器的定義:

//_Alloc為內存分配器
template<class _Ty,
    class _Alloc = allocator<_Ty>>
class deque{
    ...
protected:
    iterator start;
    iterator finish;
    map_pointer map;
...
}

其中,start 迭代器記錄著 map 數(shù)組中首個連續(xù)空間的信息,finish 迭代器記錄著 map 數(shù)組中最后一個連續(xù)空間的信息。另外需要注意的是,和普通 deque 迭代器不同,start 迭代器中的 cur 指針指向的是連續(xù)空間中首個元素;而 finish 迭代器中的 cur 指針指向的是連續(xù)空間最后一個元素的下一個位置。

因此,deque 容器的底層實現(xiàn)如下圖所示:

借助 start 和 finish,以及 deque 迭代器中重載的諸多運算符,就可以實現(xiàn) deque 容器提供的大部分成員函數(shù),比如:

//begin() 成員函數(shù)
iterator begin() {return start;}
//end() 成員函數(shù)
iterator end() { return finish;}
//front() 成員函數(shù)
reference front(){return *start;}
//back() 成員函數(shù)
reference back(){
    iterator tmp = finish;
    --tmp;
    return *tmp;
}
//size() 成員函數(shù)
size_type size() const{return finish - start;}//deque迭代器重載了 - 運算符
//enpty() 成員函數(shù)
bool empty() const{return finish == start;}

stack和queue的原理

由stack和queue源碼可知,其實stack和queue是將deque容器進行再封裝,其底層是一個deque容器。對stack和queue操作,其實間接操作的是deque容器。

到此這篇關于C++ deque/queue/stack的底層原理的文章就介紹到這了,更多相關C++ deque/queue/stack的底層原理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++ Boost Atomic詳細講解

    C++ Boost Atomic詳細講解

    Boost是為C++語言標準庫提供擴展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標準庫的后備,是C++標準化進程的開發(fā)引擎之一,是為C++語言標準庫提供擴展的一些C++程序庫的總稱
    2022-11-11
  • OpenCV獲取視頻的每一幀并保存為.jpg圖片

    OpenCV獲取視頻的每一幀并保存為.jpg圖片

    這篇文章主要為大家詳細介紹了OpenCV獲取視頻的每一幀,并保存為.jpg圖片,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • C++雙線程調用網絡攝像頭與多線程調用多攝像頭同步執(zhí)行方法詳細講解

    C++雙線程調用網絡攝像頭與多線程調用多攝像頭同步執(zhí)行方法詳細講解

    這篇文章主要介紹了C++雙線程調用網絡攝像頭與多線程調用多攝像頭同步執(zhí)行方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-11-11
  • C語言 結構體(Struct)詳解及示例代碼

    C語言 結構體(Struct)詳解及示例代碼

    本文主要介紹C語言 結構體的知識,學習C語言肯定需要學習結構體,這里詳細說明了結構體并附示例代碼,供大家參考學習,有需要的小伙伴可以參考下
    2016-08-08
  • C++實現(xiàn)LeetCode(146.近最少使用頁面置換緩存器)

    C++實現(xiàn)LeetCode(146.近最少使用頁面置換緩存器)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(146.近最少使用頁面置換緩存器),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-07-07
  • C++命令行解析包gflags的使用教程

    C++命令行解析包gflags的使用教程

    這篇文章主要給大家介紹了關于C++命令行解析包gflags的使用教程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • 帶你用C語言實現(xiàn)strtok和字符串分割函數(shù)

    帶你用C語言實現(xiàn)strtok和字符串分割函數(shù)

    下面小編就為大家?guī)硪黄猚語言中字符串分割函數(shù)及實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-09-09
  • C++中事件機制的簡潔實現(xiàn)及需要放棄的特性

    C++中事件機制的簡潔實現(xiàn)及需要放棄的特性

    事件模型是被廣泛使用的好東西,但是C++標準庫里沒有現(xiàn)成的,現(xiàn)在VC11可以用在XP下了,那么就痛快的拿起C++11提供的先進設施組合出一個輕便的實現(xiàn)吧感興趣的朋友可以了解下,或許對你有所幫助
    2013-02-02
  • Qt實現(xiàn)定時器的兩種方法分享

    Qt實現(xiàn)定時器的兩種方法分享

    這篇文章主要為大家詳細介紹了Qt中實現(xiàn)定時器的兩種不同方法,文中的示例代碼講解詳細,對我們了解Qt有一定的幫助,感興趣的可以跟隨小編一起學習一下
    2022-11-11
  • 盤點分析C語言中少見卻強大的字符串函數(shù)

    盤點分析C語言中少見卻強大的字符串函數(shù)

    這篇文章主要為大家盤點及分析C語言中少見卻強大的字符串函數(shù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-02-02

最新評論