數組、鏈表、棧、隊列和STL


數組

數組是一種最基本的數據結構,它是內存上的一塊連續存儲空間。正因如此數組的隨機訪問很方便。但數組也有其固有的限制,大小分配后不能改變。

STL中的數組

STL中的Array是靜態數組模板,就是我們所說的數組。使用方法如下。    

std::array<int, 3> a1 = { 1, 2, 3 };

std::array<std::string, 2>a3 = {"a","b"};

STL中的Vector是動態數組模板,根據需要動態的分配內存。Vector的采用加倍的擴容策略。Push_back()最壞情況,最好和平均情況是。數組和動態數組常用來組成更復雜的數據結構。

 

鏈表

鏈表是一種線性表(有n個元素組成的有限序列),鏈表是一種基礎的數據結構,通常有一連串的節點組成。節點中存放數據和指向下一節點的指針。因為鏈表不是按線性的順序存儲結構,其查詢某節點的時間是,插入操作。鏈表分為單鏈表,雙鏈表和循環鏈表。

 

單鏈表

 

雙鏈表

 

 

循環單鏈表

循環雙鏈表

鏈表的性能比較

單鏈表和雙鏈表的查詢時間最好情況,最壞和平均情況。

單鏈表涉及到向前訪問的操作Before(),InsertBefore(),Remove()最壞和平均情況,最好情況。其他查詢更新操作。

雙鏈表的所有操作都是。

STL中的鏈表

List是用普通雙鏈表實現的,如果在實際應用中需要使用鏈表,那么首先應該選擇List。或者將List作為其成員。

鏈表和數組的對比

數組

動態數組

鏈表

快速的隨機訪問

快速的隨機訪問

快速的插入和刪除

大小受限

動態分配

容量不受限

插入刪除費時

插入刪除費時

隨機訪問慢

Forward_list是C++11添加的,實現為一種簡單的單鏈表,沒有size()成員,只有前向迭代器沒有反向迭代器。

 

棧是一種后進先出的數據結構,可以用數組也可用鏈表實現。鏈表的實現形式更接近於棧的抽象概念,因為鏈表的節點數與棧中元素數目相同,而在數組實現形式中,數組的容量常常超過其尺寸。棧的直接應用包括函數調用,網頁瀏覽記錄,編輯器中的重做。。。棧也是其它數據結構和算法的基本組件。

順序棧(用數組實現的棧)

鏈式棧(用鏈表實現的棧)

 

棧的性能比較

STL中的棧

STL中的stack是一種容器適配器,就是用其他容器最為底層實現,將其他容器轉化為棧。Stack封裝了入棧,出棧,取棧頂元素,查看大小和是否為空操作。默認情況下,stack用deque做底層容器。也可以將其修改為vector,list。

std::stack<int> deque_stack;

std::stack<int, std::vector<int>> vec_stack;

std::stack<int, std::list<int>> list_stack;

 

隊列

隊列是一種先進先出的數據結構,可以用數組也可以用鏈表實現隊列。隊列可用訪問共享資源,排隊購物。還用來構成其他更復雜的數據結構。

基於數組的隊列

基於鏈表的隊列

 

隊列的性能分析

雙端隊列

雙端隊列的性能分析

優先隊列

許多情況下隊列的先入先出機制不能滿足要求,此時需通過優先規則來完善入隊出隊的機制。優先隊列應用而生。實現方式有兩種:1.基於有序鏈表的實現,插入操作,刪除操作;2.基於無序鏈表的實現,插入操作,刪除操作。

 

堆(堆放在這里說是因為最大堆可用來實現優先隊列)

堆是一種數據結構,完全二叉樹,但在實現方式上沒有選擇一般的二叉樹數據結構(即一個結點包含兩個指向孩子的指針)而使用了數組。要明白堆的含義,必須知道什么是完全二叉樹,完全二叉樹是有滿二叉樹引起的,了解滿二叉樹也是必要的。

 

一般的樹中,某結點的高度和深度的定義。

滿二叉樹: 如果一個二叉樹的任意結點或者有0或者有2個孩子。

完全二叉樹:如果一個二叉樹除倒數第一層外都被填滿,並且倒數第一層從左至右填充。

完美樹:如果一個二叉樹的所有層被填滿。

堆的定義:1.是一個完全二叉樹;2.上層的節點鍵值大於下層節點鍵值(最小堆),或者相反(最大堆)。

 

基於數組實現的堆

某節點位於數組i處,做左子節點位於2i,右子節點位於2i+1,數組第一個位置未使用。

STL中的隊列

1.queue

STL中的queue是一種容器適配器,默認的底層實現容器是deque。這一點和stack很像,通過關閉或者限制deque的一些借口可以很輕松的實現stack和queue。Deque是stack和queue的幕后功臣。那么deque是怎么實現的?

2.deque

Deque是雙端隊列,它的空間構造是幾塊分段線性的存儲區。其實現細節非常復雜。

Deque是如何擴展空間的?

如果緩沖區中還有備用的空間,那么直接使用備用的空間;否則,另外配置一個緩沖區,將其信息記錄到緩沖區地址表里;更有甚者,如果緩沖區地址表都不夠的時候,緩沖區地址表也要嚴格依從"重新配置,復制,釋放"規則,但相比對"重新配置,復制,釋放"規則宗教式追狂熱的vector而言,效率高很多。侯傑老師推薦,將deque所有的元素倒騰到一個vector中,再用STL<algorithm>sort()函數,再從vector中倒騰進deque中。這種折騰是必須的,直接在的deque內部進行排序,效率更低。(引http://daoluan.net/blog/stl-deque/

3.priority_queue

Priority_queue優先級隊列是一個擁有權值概念的單向隊列queue,在STL的具體實現中也是以別的容器為底層數據結構,在利用堆的規則調整元素之間的位置。默認的底層實現是vector。這與queue的默認底層實現deque差別很大。

4.heap

STL中關於堆的操作,建堆make_heap(),加數據push_heap(),刪數據pop_heap(),堆排序sort_heap()。頭文件<algorithm>。

 

總結

數組

靜態數組=array

動態數組=vector

鏈表

單鏈表= forward_list

雙鏈表=list

隊列

單向隊列=queue(默認deque)

單向數組隊列=queue<類型,vector<類型>>

單向鏈式隊列=queue<類型,list<類型>>

雙向隊列=deque

優先隊列=priority_queue(默認vector)

堆棧

meak_heap,push_heap,pop_heap,sort_heap

 

練習

1.手寫堆

2.利用STL實現優先隊列


免責聲明!

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



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