數組
數組是一種最基本的數據結構,它是內存上的一塊連續存儲空間。正因如此數組的隨機訪問很方便。但數組也有其固有的限制,大小分配后不能改變。
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實現優先隊列