1樓:匿名使用者
1. vector 動態陣列
(1)vector有自動擴容操作,每次擴容伴隨著「配置新空間 / 移動舊資料 / 釋放舊空間」的操作,因此有一定時間成本。
(2)vector提供了reserve介面,如果能夠對元素個數有大概瞭解,可以一開始就分配合適的空間。
(3)vector的記憶體空間是連續的,對插入元素的操作而言,在vector尾部插入才是合適的選擇。維護的是一個連續線性空間,所以vector支援隨機存取。
(4)vector動態增加大小時,並不是在原空間之後持續新空間(無法保證原空間之後尚有可供配置的空間),而是以原大小的2倍另外配置一塊較大的空間,接著將原內容拷貝過來,然後才開始在原內容之後構造新元素,並釋放原空間。因此,對vector的任何操作,一旦引起空間重新配置,指向原vector的所有迭代器就都失效了。
2、vector與array的區別
vector與array非常相似。兩者的唯一區別在於空間運用的靈活性。array是靜態空間,一旦配置了就不能改變;vector是動態空間,隨著元素的加入,它的內部機制會自行擴充空間以容納新元素。
因此,vector的運用對於記憶體的合理利用與運用的靈活性有很大的幫助。
所採用的資料結構非常簡單:線性連續空間。為了降低空間配置時的速度成本,vector實際配置的大小可能比客戶端需求量更大一些,以備將來可能的擴充,這便是容量的觀念。
增加新元素時,如果容量不足,則擴充至2倍(若原大小為0,則配置為1),2倍容量仍不足,就擴充至足夠大的容量。
2.list特性
(1)相較於vector的連續線性空間,list就顯得複雜許多。
(2)它的好處是每次插入或刪除一個元素,就配置或釋放一個元素空間。因此,list對於空間的運用有絕對的精準,一點也不浪費。
(3)對於任何位置的元素插入或元素移除,list永遠是常數時間。
(4)list不僅是一個雙向連結串列,而且還是一個環狀雙向連結串列。它只需要一個指標便可完整表現整個連結串列。
(5)插入操作和接合操作都不會造成原有的list迭代器失效,這在vector是不成立的。因為vector的插入操作可能造成記憶體重新配置,導致原有的迭代器全部失效。甚至list的元素刪除操作(erase),也只有「指向被刪除元素」的那個迭代器失效,其他迭代器不受任何影響。
(6)list不再能夠像vector那樣以普通指標作為迭代器,因為其節點不保證在儲存空間中連續。list提供的是bidirectional iterators。
slist
slist與list的區別:
(1)stl list是雙向連結串列,而slist是單向連結串列。
(2)stl list的迭代器是雙向的bidirectional iterator,而slist的迭代器是單向的forward iterator。
(3)單向連結串列所耗用的空間更小,某些操作更快。
(4)兩者有一個共同特點:插入(insert)、刪除(erase)、接合(splice)等操作不會造成**迭代器的失效。(指向被移除元素的那個迭代器,在移除操作後肯定會失效)。
(5)因為單連結串列只能往前迭代,所以很多操作都沒有提供,即使提供了,也是非常低效的操作,需要從頭結點開始遍歷。
除了slist起點處附近的區域之外,在其他位置上採用insert或erase操作函式,都屬不智之舉,這便是slist相較於list的大缺點。
(6)slist迭代器是單向的forward iterator,因此除了迭代器的基本操作之外,只實現了operator++操作。
deque
1、deque與vector的區別
(1)vector是單向開口的連續線性空間,使用者只能在vector尾部進行插入刪除操作(也允許在某個pos處插入,但由於vector的底層實現是陣列,過多非隊尾位置的插入會有效能上的消耗)。而deque是一種雙向開口的連續線性空間,允許在頭尾兩端分別做插入和刪除操作。
(2)deque允許在常數時間內對起頭端進行元素的插入或移除操作。
(3)deque沒有所謂容量概念。它是動態地用分段連續的空間組合而成,隨時可以增加一段新的空間並連線起來。沒有必要提供所謂的空間保留(reserve)功能。
(4)deque的最大任務,便是在這些分段的定量連續空間上,維護其整體連續的假象,並提供隨機存取的介面。避開了「重新配置、複製、釋放」的輪迴,代價則是複雜的迭代器架構。
(5)既是分段連續線性空間,就必須有**控制,而為了維持整體連續的假象,資料結構的設計及迭代器前進後退等操作都頗為繁瑣。deque的實現**分量遠比vector或list都多得多。所以,我們應儘可能選擇vector而非deque。
2、deque的中控器
deque採用一塊所謂的map(注意,不是stl的map容器)作為主控。這裡所謂map是一小塊連續空間,其中每個元素(此處稱為一個節點,node)都是指標,指向另一段(較大的)連續線性空間,稱為緩衝區。緩衝區才是deque的儲存空間主體。
sgi stl 允許我們指定緩衝區大小,預設值0表示將使用512 bytes 緩衝區。
總結:(1)map是塊連續空間,其內的每個元素都是一個指標,指向一塊緩衝區。
(2)進一步發現,map其實是一個t**,也就是說它是一個指標,所指之物又是一個指標,指向型別為t的一塊空間。
3、deque的迭代器
deque是分段連續空間。維持其」整體連續」假象的任務,落在了迭代器的operator++和operator–兩個運運算元身上。
deque的迭代器應該具備什麼結構:
(1)它必須能夠指出分段連續空間(亦即緩衝區)在**
(2)它必須能夠判斷自己是否已經處於其所在緩衝區的邊緣,如果是,一旦前進或後退就必須跳躍至下一個或上一個緩衝區。為了能夠正確跳躍,deque必須隨時掌握管控中心(map)。
deque在效率上不如vector,因此有時候在對deque進行sort的時候,需要先將元素移到vector再進行sort,然後移回來。
4、deque的構造與記憶體管理
由於deque的設計思想就是由一塊塊的快取區連線起來的,因此它的記憶體管理會比較複雜。插入的時候要考慮是否要跳轉快取區、是否要新建map節點(和vector一樣,其實是重新分配一塊空間給map,刪除原來空間)、插入後元素是前面元素向前移動還是後面元素向後面移動(誰小移動誰)。而在刪除元素的時候,考慮是將前面元素後移覆蓋需要移除元素的地方還是後面元素前移覆蓋(誰小移動誰)。
移動完以後要析構冗餘的元素,釋放冗餘的快取區。
4.stack
stack是一種先進後出的資料結構,只有一個出口。允許新增元素、移除元素、取得最頂端元素。不允許有遍歷行為。
在sgi stl的原始碼的設計中,它是基於某種容器作為底部結構的,預設容器是deque容器,使用者也可以自己指定容器的型別。
stack不提供走訪功能,也不提供迭代器。
5.queue
queue是一種先進先出的資料結構。有兩個出口,允許新增、移除元素、從最底端加入、取得最頂端元素。不允許遍歷行為。
deque是雙向佇列,而queue是單向佇列。
deque是雙向開口的資料結構,若以deque為底部結構並封閉其底端出口和前端入口,便輕而易舉的形成了一個queue。因此,sgi stl以deque作為預設情況下的queue底部結構。
queue不提供遍歷功能,也不提供迭代器。
map和multimap
map的特性:
(1)所有元素都會根據元素的鍵值自動被排序。
(2)map的所有元素都是pair,第一個值是鍵值,第二個是實值。
(3)map不允許兩個元素擁有相同的鍵值。
(4)可以通過map的迭代器來改變元素的實值,但不可以改變鍵值,那樣會違反元素的排列規則。
(5)在客戶端對map進行插入或刪除操作後,之前的迭代器依然有效。當然,被刪除的元素的迭代器是個例外。
(6)它的底層機制是rb-tree。幾乎所有的操作都只是轉呼叫rb-tree的操作行為而已。
multimap和map幾乎一樣,唯一的區別是,multimap允許鍵值重複。因此map使用底層rb-tree的insert_unique()實現插入,而multimap插入採用的是rb-tree的insert_equal()而非insert_unique()。
hashtable
1、hashtable概述
hashtable可以提供對任意有名項的存取和刪除操作,這種結構的用意在於提供常數時間的的基本操作,而不依賴於插入元素的隨機性,是以統計為基礎的。
雜湊函式(hash function):負責將某一元素對映為一個」大小可接受之索引」。簡而言之,就是將大數對映為小數。
使用hash function帶來的問題:可能有不同元素對映到相同的位置(相同索引)。這便是碰撞或衝突問題。
解決碰撞問題的方法:線性探測(linear probing),二次探測(quadratic probing),開鏈(separate chaining)等。stl hashtable採用的hash方式是開鏈法。
需要兩個假設:a.**足夠大。b.每個元素都能夠獨立。
線性探測會造成主集團(primary clustering)問題:平均插入成本的成長幅度,遠高於負載係數的成長幅度。
(2)二次探測:主要用來解決主集團問題。解決碰撞的方程式為f(i) = i^2。
如果hash function計算出新元素的位置為h,而該位置實際上已被使用,那麼就依次嘗試h+1^2,h+2^2,h+3^2,h+4^2,….,h+i^2,而不像線性探測嘗試的是h+1,h+2,h+3,h+4,….,h+i。
二次探測可以消除主集團,卻可能造成次集團(secondary clustering):兩個元素經hash function計算出來的位置若相同,則插入時所探測的位置也相同,形成某種浪費。消除次集團的方法如複式雜湊。
(3)開鏈:這種做法是在每一個**元素中維護一個list。hash function為我們分配某一個list,然後我們在哪個list身上執行元素的插入、搜尋、刪除等操作。
若list夠短,速度還是夠快。
使用開鏈法,**的負載係數將大於1。sgi stl hashtable便採用的是開鏈法。
更多c++知識歡迎來我的部落格:網頁連結
蠍子的生活習性,講一下關於蠍子生活習性
熟悉其生活規律 養蠍本身就非易事,如果不瞭解蠍子的習性有哪些更是會給養蠍帶來很大的不便。所以在飼養之前應當對其習性做一定的瞭解,有助於日後飼養。蠍子的生活習性就是蠍子的生活規律,也是人工養蠍的理論基礎。只有掌握蠍子的生活規律,才能更好的養蠍。在網路上和書本上也有很多介紹蠍子的生活習性的知識,很多養蠍...
請問一下關於車禍工傷的問題,請問一下關於車禍工傷的問題
您好,以下是我辛辛苦苦找來的資料!雖然不是自己寫的,希望對你有幫助最高人民法院副院長黃鬆有就 最高人民法院關於審理人身損害賠償案件適用法律若干問題的解釋 答記者問 受害人獲工傷保險賠付不免除第三人的侵權責任問 發生工傷事故,工傷職工除享受工傷保險待遇外,能否再請求民事損害賠償?答 工傷保險與民事損害...
想問一下關於信用卡的問題,想問一下關於信用卡的問題
若是招行信用卡,本期應還款金額是負數,說明多還款了,本期不用還了。關於信用卡的幾個問題 1.這個月我消費三千,那下個月我就要在規定的時間存三千塊進去,也就是說信用卡要每個月保證有五千咯。那如果還不起怎麼辦。答 信用卡里面是沒有錢的,是有你花錢的額度。當然裡面可以你存錢,但是沒有利息。一個月刷卡消費3...