c/c++ set,map的用法及區別
阿新 • • 發佈:2021-01-08
STL總共實現了兩種不同結構的管理式容器:樹型結構與雜湊結構。樹型結構的關聯式容器主要有四種:set,map,multiset,multimap。下面介紹一下主要介紹set和nultiset的用法,及set與map的區別,具體map的用法示例見連結。
1.set
set裡面每個元素只存有一個key值,它支援高效的關鍵字查詢操作,比如檢查一個關鍵字是否在set中。如果這個key值之前存在的話就不插入(有序,無重複)。
簡單使用如下:
插入:
set<int> s;
s.insert(2);
s.insert(1);
s.insert (4);
s.insert(5);
s.insert(3);
s.insert(5);
s.insert(5);
s.insert(5);
s.insert(5);
s.insert(5);
for (auto e : s)
{
cout << e << " ";
}
cout << endl;
插入如上資料之後,打印出來的值為1 2 3 4 5。set容器自動對以上資料進行了排序,並且實現了去重。但是不能對set裡的值進行修改。
查詢:
//時間複雜度:O(logN)----底層是搜尋樹
set<int> ::iterator pos = s.find(3);
//時間複雜度:O(N)----需要遍歷一遍(不建議使用)
//set<int>::iterator pos = find(s.begin(), s.end(), 3);
if (pos != s.end())
{
cout << "找到了" << endl;
}
set容器中的find查詢效率高,因為底層是一個二叉搜尋樹,比要查詢的值小就去左子樹查詢,反之則去右子樹查詢。
刪除:
//時間複雜度:O(logN)----底層是搜尋樹
set<int>::iterator pos = s.find(3);
//時間複雜度:O(N)----需要遍歷一遍(不建議使用)
//set<int>::iterator pos = find(s.begin(), s.end(), 3);
if (pos != s.end())
{
cout << "找到了" << endl;
}
採用s.erase(3);這種操作如果沒有3並不會報錯,如果有3則會刪除這個結點。
找到pos位置,採用s.erase(pos);這種操作如果沒有3則會報錯,如果有3則會刪除這個結點。
交換:
//時間複雜度:O(logN)----底層是搜尋樹
set<int>::iterator pos = s.find(3);
//時間複雜度:O(N)----需要遍歷一遍(不建議使用)
//set<int>::iterator pos = find(s.begin(), s.end(), 3);
if (pos != s.end())
{
cout << "找到了" << endl;
}
兩個set的交換的其實是交換結點的指標,效率高。
清空:
//時間複雜度:O(logN)----底層是搜尋樹
set<int>::iterator pos = s.find(3);
//時間複雜度:O(N)----需要遍歷一遍(不建議使用)
//set<int>::iterator pos = find(s.begin(), s.end(), 3);
if (pos != s.end())
{
cout << "找到了" << endl;
}
遍歷:
//時間複雜度:O(logN)----底層是搜尋樹
set<int>::iterator pos = s.find(3);
//時間複雜度:O(N)----需要遍歷一遍(不建議使用)
//set<int>::iterator pos = find(s.begin(), s.end(), 3);
if (pos != s.end())
{
cout << "找到了" << endl;
}
2. multiset
其實整體的介面和set都相同,但是multiset可以插入key相同的值。(允許重複)
multiset<int> ms;
ms.insert(2);
ms.insert(1);
ms.insert(4);
ms.insert(5);
ms.insert(3);
ms.insert(5);
ms.insert(5);
ms.insert(5);
ms.insert(5);
ms.insert(5);
for (auto e : ms)//可以重複插入相同key值
{
cout << e << " ";
}
cout << endl;
auto pos = ms.find(5);
if (pos != ms.end())
{
cout << "找到了" << endl;//找到的是中序的第一個5
while (*pos == 5)//往後繼續找可以找到後面所有的5
{
cout << *pos << endl;
++pos;
if (pos == ms.end())//pos指向最後一個的下一個
break;
}
}
--pos;//倒數第一個5
ms.erase(pos);
for (auto e : ms)//可以重複插入相同key值
{
cout << e << " ";
}
cout << endl;
multiset允許key的冗餘,如果用find查詢key值時,找到的是中序遍歷第一個,因此不斷遍歷下午可以找到這個multiset裡所有的key值。
multiset和set一樣不能夠對資料進行修改。
set和map特性和區別
set是一種關聯式容器,其特性如下:
- set以RBTree作為底層容器
- 所得元素的只有key沒有value,value就是key
- 不允許出現鍵值重複
- 所有的元素都會被自動排序
- 不能通過迭代器來改變set的值,因為set的值就是鍵
map和set一樣是關聯式容器,它們的底層容器都是紅黑樹,區別就在於map的值不作為鍵,鍵和值是分開的。它的特性如下:
- map以RBTree作為底層容器
- 所有元素都是鍵+值存在
- 不允許鍵重複
- 所有元素是通過鍵進行自動排序的
- map的鍵是不能修改的,但是其鍵對應的值是可以修改的
轉載自: https://blog.csdn.net/ETalien_/article/details/89439892