1. 程式人生 > 其它 >c/c++ set,map的用法及區別

c/c++ set,map的用法及區別

技術標籤:C/C++c++容器setmap

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是一種關聯式容器,其特性如下:

  1. set以RBTree作為底層容器
  2. 所得元素的只有key沒有value,value就是key
  3. 不允許出現鍵值重複
  4. 所有的元素都會被自動排序
  5. 不能通過迭代器來改變set的值,因為set的值就是鍵

map和set一樣是關聯式容器,它們的底層容器都是紅黑樹,區別就在於map的值不作為鍵,鍵和值是分開的。它的特性如下:

  1. map以RBTree作為底層容器
  2. 所有元素都是鍵+值存在
  3. 不允許鍵重複
  4. 所有元素是通過鍵進行自動排序的
  5. map的鍵是不能修改的,但是其鍵對應的值是可以修改的

轉載自: https://blog.csdn.net/ETalien_/article/details/89439892