1. 程式人生 > 其它 >C++STL標準庫學習筆記(三)multiset

C++STL標準庫學習筆記(三)multiset

對STL標準庫中multiset部分簡單做了下筆記

C++STL標準庫學習筆記(multiset

  STL中的平衡二叉樹資料結構

前言:

  在這個筆記中,我把大多數程式碼都加了註釋,我的一些想法和註解用藍色字型標記了出來,重點和需要關注的地方用紅色字型標記了出來。

介紹:

  有時需要在大量增加,刪除資料的同時,還需要大量資料的查詢

  我們希望增加資料,刪除資料,查詢資料都能在log(n)複雜度完成

  排序+二分查詢顯然不行,因為加入新資料就要重新排序。

  在這個時候!我們就可以使用“平衡二叉樹”資料結構存放資料,體現在STL中就是以下四種“排序容器”

  multiset set multimap map

  英語課:set:集合

  反正我們只管用就行了,具體實現應該可以參考《STL原始碼剖析》

  從這裡開始就需要有一定程度的資料結構和C++面向物件的知識了,如果忘記的話可以去複習一下,當然,這裡我們只要會用就行了,不需要特別深的理解。

1.1multiset用法

  multiset<T> st;

  定義了一個叫multiset變數st,st裡面可以存放T型別的資料(自定義元素也行),並且能夠自動排序。開始st為空。

  排序規則:表示式“a < b”為true,則a排在b前面

  可用st.insert新增元素,st.find查詢元素,st.erase刪除元素,複雜度都是log(n)(還有好多函式,這個就要自己去研究了,以後有機會也會來補充的)

1.2 multiset上的迭代器

  multiset<T>::iterator p;

  p是迭代器,(大致)相當於指標,可用於指向multiset中的元素。訪問multiset中的元素要通過迭代器。

  與指標的不同:

  multiset上的迭代器可++,--,用!=和==比較,不可比大小,不可加減整數,不可相減。(指標就能這樣操作,可以用來算長度啥的)

  multiset<T> st;

  st.begin()返回值型別為 multiset<T>::iterator,是指向st中的頭一個元素的迭代器。

  st.end()返回值型別為 multiset<T>::iterator,是指向st中的最後一個元素後面

的迭代器。(有沒有一種既視感,就是[ st.begin(), st.end() )和前面sort的範圍很像,不過估計是因為迭代器不能比較大小,為了方便判斷全部遍歷過了就讓st.end()指向了最後一個的後面,訪問到st.end()時剛好退出)

  對迭代器 ++ ,其就指向容器中下一個元素,-- 令其指向上一個元素。

  樣例:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<set>//使用multiset和set需要
 4 using namespace std;
 5 int main(int argc, char const *argv[])
 6 {
 7     multiset<int>st;
 8     int a[10] = {1,14,12,13,7,13,21,19,8,8};
 9     for (int i = 0; i < 10; i++)
10     {
11         st.insert(a[i]);//插♂入的是a[i]的複製品
12     }
13     multiset<int>::iterator i;//迭代器,近似於指標
14     for ( i = st.begin(); i != st.end(); i++)
15     {
16         cout<<*i<<",";//輸出:1,7,8,8,12,13,13,14,19,21,
17     }
18     cout<<endl;
19     i = st.find(22);//查詢22,返回值是迭代器
20     if (i == st.end())//查詢不到則返回值為end()
21     {
22         cout<<"Not Found"<<endl;//輸出:Not Found
23     }
24     st.insert(22);//插入22
25     i = st.find(22);
26     if (i == st.end())
27     {
28         cout<<"Not Found"<<endl;
29     }
30     else
31     {
32         cout<<"Found:"<<*i<<endl;//輸出:Found:22
33     }//找到則返回指向找到的元素的迭代器
34 
35     i = st.lower_bound(13);
36     //返回最靠後的迭代器it,使得[begin,it)中的元素
37     //都在13前面,複雜度log(n)
38     cout<<*i<<endl;//結果:13
39     i = st.upper_bound(8);
40     //返回最靠前的迭代器it,使得[it,end())中的元素
41     //都在8後面,複雜度log(n)
42     cout<<*i<<endl;//結果:12
43     st.erase(i);//刪除迭代器i指向的元素,即12
44     for ( i = st.begin(); i != st.end(); i++)
45     {
46         cout<<*i<<",";//輸出:1,7,8,8,13,13,14,19,21,22,
47     }
48     
49     return 0;
50 }
樣例

  程式中部分重要的地方單獨拎出來強調:

  i = st.find(22);

  作用是查詢22,返回值是迭代器

  i = st.lower_bound(13);

  返回最靠後的迭代器it,使得[begin,it)中的元素

  都在13前面,複雜度log(n)

  i = st.upper_bound(8);

  返回最靠前的迭代器it,使得[it,end())中的元素

  都在8後面,複雜度log(n)

  st.erase(i);

  刪除迭代器i指向的元素

1.3後記:

  從這裡開始就有資料結構那味了,如果平衡二叉樹忘記的話,記得去看看(雖然我覺得邏輯理解了,會用就行)。另外,可以看見這裡的用法和前面sort,binary_search之類也有相似之處,估計學完一部分STL標準庫內容,其他內容看到函式名就會用了。感謝大家讀到這裡,祝大家健康快樂吉祥如意恭喜發財學業有成早生貴子年年有餘,以及頭髮茂密,下篇部落格再見拜拜。