set集合容器

來源:互聯網
上載者:User

標籤:

近期學習了STL中set的使用,在此寫一點點總結和自己的一些體悟。

     set集合容器實現了紅/黑樹狀結構(Red-Black Tree)的平衡二叉檢索樹的的資料結構,在插入元素時,它會自動調整二叉樹的排列,把該元素放到適當的位置,以確保每個子樹根節點的索引值大於左子樹所有節點的索引值,而小於右子樹所有節點的索引值;另外,還得確保根節點的左子樹的高度與有字數的高度相等,這樣,二叉樹的高度最小,從而檢索速度最快。要注意的是,它不會重複插入相同索引值的元素,而採取忽略處理。

     平衡二叉檢索樹的檢索使用中序遍曆演算法,檢索效率高於vector、deque、和list的容器。另外,採用中序遍曆演算法可將索引值由小到大遍曆出來,所以,可以理解為平衡二叉檢索樹在插入元素時,就會自動將元素按索引值從小到大的順序排列。

     那麼現在有人就要問了,為何set的插入、刪除、檢索效率要比其他序列容器高?

首先我們要瞭解set的儲存方式,set內部採用的是紅/黑樹狀結構(也稱為RB樹),紅/黑樹狀結構是一種非常高效的平衡檢索二叉樹。基於紅/黑樹狀結構,set容器內所有元素都是以節點的方式來儲存,其節點結構和鏈表差不多,指向父節點和子節點。結構圖可能如下:

      A
   / \
  B C
 / \ / \
  D E F G

因此插入的時候只需要稍做變換,把節點的指標指向新的節點就可以了。刪除的時候類似,稍做變換後把指向刪除節點的指標指向其他節點也OK了。這裡的一切操作就是指標換來換去,和記憶體移動沒有關係。

那麼當資料元素增多時,set的插入、刪除和搜尋速度變化如何呢?

如果你知道log2的關係你應該就徹底瞭解這個答案。在set中尋找是使用二分尋找,也就是說,如果有16個元素,最多需要比較4次就能找到結果,有32個元素,最多比較5次。那麼有10000個呢?最多比較的次數為log10000,最多為14次,如果是20000個元素呢?最多不過15次。看見了吧,當資料量增大一倍的時候,搜尋次數只不過多了1次,多了1/14的搜尋時間而已。你明白這個道理後,就可以安心往裡面放入元素了。

 

使用set前,需要在程式標頭檔中包含聲明“#include<set>”。

 

下面我們列出一些set中的常用操作:(英語好的小夥伴可以進這個連結看看,包含了set的幾乎所有操作)

首先是建立set集合對象:

1 #include<set>2 3 using namespace std;4 5 int main(){6     set<int> s;//定義元素類型為int的集合對象,當前沒有任何元素 7     return 0;8 }

元素的插入與中序遍曆:

採用inset()方法把元素插入到集合中,插入規則在預設的比較規則下,是按元素值從小到大插入,如果自己指定了比較規則函數,則按自訂比較規則函數插入。使用前向迭代器對集合中序遍曆,結果正好是元素排序後的結果。

 1 #include<iostream> 2 #include<set> 3 using namespace std; 4  5 int main(){ 6     set<int> s; 7     s.insert(8);//插入了五個元素,但由於第二次插入8有重複,所以第二次插入8並沒有執行  8     s.insert(1); 9     s.insert(12);10     s.insert(6);11     s.insert(8);12 13     set<int>::iterator it;//定義前向迭代器 14     for(it=s.begin();it!=s.end();it++){    //中序遍曆集合中的所有元素 15         cout<<*it<<" ";16     }17     cout<<endl;18     return 0;19 } 

運行結果:

1 6 8 12

 

我們也可以使用反向迭代器reverse_iterator來反向遍曆集合,輸出結果正好是集合元素的反向排序結果。它需要用到rbegin()和rend()兩個方法,他們分別給出了反向遍曆的開始位置和結束位置。

 1 #include<iostream> 2 #include<set> 3 using namespace std; 4  5 int main(){ 6     set<int> s; 7     s.insert(8);//插入了五個元素,但由於第二次插入8有重複,所以第二次插入8並沒有執行  8     s.insert(1); 9     s.insert(12);10     s.insert(6);11     s.insert(8);12     13     set<int>::reverse_iterator it;//定義反向迭代器 14     for(it=s.rbegin();it!=rend();it++){//反向遍曆 15         cout<<*it<<" ";16     }17     cout<<endl;18     return 0;19 }

運行結果

12 8 6 1

 

元素的刪除:

元素可以使用erase()來刪除某索引值的元素,也可以使用clear()來清空集合。

明天更,哈哈

set集合容器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.