set集合容器:實現了紅黑樹的平衡二叉檢索樹的資料結構,插入元素時,它會自動調整二叉樹的排列,把元素放到適當的位置,以保證每個子樹根節點鍵值大於左子樹所有節點的鍵值,小於右子樹所有節點的鍵值;另外,還得保證根節點左子樹的高度與右子樹高度相等。
平衡二叉檢索樹使用中序遍歷演算法,檢索效率高於vector、deque和list等容器,另外使用中序遍歷可將鍵值按照從小到大遍歷出來。
構造set集合主要目的是為了快速檢索,不可直接去修改鍵值。
標頭檔案:#include
set的操作有很多,下面是幾種比較常用的
1.元素插入:s.
insert(2
);//把2放入到集合中
2.元素刪除:s.
erase(2
);//刪除鍵值為2的元素
3.元素清空:s.
clear()
;//刪除元素中所有元素
4.元素檢索:s.
find(2
);//在s中查詢2,若找到,返回該元素迭代器的位置,否則,返回最後乙個元素後面乙個位置。
5.集合是否為空:s.
empty()
;//集合為空時返回true
6.檢查元素個數:s.
count(2
);// 返回值為2的元素的個數
7.二分查詢:s.
lower_bound(2
);//返回指向大於(或等於)2的第乙個元素的迭代器
s.upper_bound(2
);//返回大於2的迭代器
8.集合元素個數:s.
size()
//集合中元素的數目
標準庫提供set關聯容器分為:
1,按關鍵字有序儲存元素:set(關鍵字即值,即只儲存關鍵字的容器);multiset(關鍵字可重複出現的set);
2,無序集合:unordered_set(用雜湊函式組織的set);unordered_multiset(雜湊組織的set,關鍵字可以重複出現)。
set就是關鍵字的簡單集合。當只是想知道乙個值是否存在時,set是最有用的。
在set中每個元素的值都唯一,而且系統能根據元素的值自動進行排序。set中元素的值不能直接被改變。set內部採用的是一種非常高效的平衡檢索二叉樹:紅黑樹,也稱為rb樹(red-black tree)。rb樹的統計效能要好於一般平衡二叉樹。
set具備的兩個特點:
set中的元素都是排序好的
set中的元素都是唯一的,沒有重複的
set容器中只能儲存鍵,是單純的鍵的集合,其中鍵是不能重複的。
set支援大部分的map的操作,但是set不支援下標的操作
1、set物件的定義和初始化
set物件的定義和初始化方法包括:
set s;
sets(s1)
;set
s(b, e)
;
2、set中資料的插入
與map不同,set中資料只能通過insert()函式進行插入。
#include
#include
#include
using
namespace std;
intmain()
set<
int> s;
s.insert
(v.begin()
, v.
end())
; set<
int>
::iterator it;
for(it = s.
begin()
; it != s.
end(
); it++
)printf
("\n");
s.insert(10
);for(it = s.
begin()
; it != s.
end(
); it++
)printf
("\n");
return0;
}
3、從set中查詢和讀取元素
從set中查詢同樣可以使用count()函式和find()函式
#include
#include
#include
using
namespace std;
intmain()
set<
int> s;
s.insert
(v.begin()
, v.
end())
; set<
int>
::iterator it;
for(it = s.
begin()
; it != s.
end(
); it++
)printf
("\n");
printf
("%d\n"
, s.
count(9
));printf
("%d\n",*
(s.find(9
)));
return0;
}
4、從set中刪除元素
從set中刪除元素使用到的函式是erase()函式,主要有以下的幾種形式:
erase(k);
erase§;
erase(b, e);
其中,p表示的迭代器指向的元素,b和e分別是迭代器的開始和結束。
#include
#include
#include
using
namespace std;
intmain()
set<
int>
s(v.
begin()
, v.
end())
; set<
int>
::iterator it;
for(it = s.
begin()
; it != s.
end(
); it++)}
s.erase
(it, s.
end())
; set<
int>
::iterator it_1;
for(it_1 = s.
begin()
; it_1 != s.
end(
); it_1++
)printf
("\n");
return0;
}
關於set有下面幾個問題:
(1)為何map和set的插入刪除效率比用其他序列容器高?
大部分人說,很簡單,因為對於關聯容器來說,不需要做記憶體拷貝和記憶體移動。說對了,確實如此。set容器內所有元素都是以節點的方式來儲存,其節點結構和鍊錶差不多,指向父節點和子節點。結構圖可能如下:
a/ \
b c/ \ / \
d e f g
因此插入的時候只需要稍做變換,把節點的指標指向新的節點就可以了。刪除的時候類似,稍做變換後把指向刪除節點的指標指向其他節點也ok了。這裡的一切操作就是指標換來換去,和記憶體移動沒有關係。
(2)為何每次insert之後,以前儲存的iterator不會失效?
iterator這裡就相當於指向節點的指標,記憶體沒有變,指向記憶體的指標怎麼會失效呢(當然被刪除的那個元素本身已經失效了)。相對於vector來說,每一次刪除和插入,指標都有可能失效,呼叫push_back在尾部插入也是如此。因為為了保證內部資料的連續存放,iterator指向的那塊記憶體在刪除和插入過程中可能已經被其他記憶體覆蓋或者記憶體已經被釋放了。即使時push_back的時候,容器內部空間可能不夠,需要一塊新的更大的記憶體,只有把以前的記憶體釋放,申請新的更大的記憶體,複製已有的資料元素到新的記憶體,最後把需要插入的元素放到最後,那麼以前的記憶體指標自然就不可用了。特別時在和find等演算法在一起使用的時候,牢記這個原則:不要使用過期的iterator。
(3)當資料元素增多時,set的插入和搜尋速度變化如何?
如果你知道log2的關係你應該就徹底了解這個答案。在set中查詢是使用二分查詢,也就是說,如果有16個元素,最多需要比較4次就能找到結果,有32個元素,最多比較5次。那麼有10000個呢?最多比較的次數為log10000,最多為14次,如果是20000個元素呢?最多不過15次。看見了吧,當資料量增大一倍的時候,搜尋次數只不過多了1次,多了1/14的搜尋時間而已。你明白這個道理後,就可以安心往裡面放入元素了。
如果對您有幫助的的話,歡迎點讚哦~謝謝
C STL set和multiset的用法
c stl set和multiset的使用 std sets 那個s這個物件裡面存貯的元素是從小到大排序的,因為用std less作為比較工具。1,set的含義是集合,它是乙個有序的容器,裡面的元素都是排序好的,支援插入,刪除,查詢等操作,就 像乙個集合一樣。所有的操作的都是嚴格在logn時間之內完...
C STL set用法手冊記錄
匯入 include using namespace std 建立set set int setname int 可換為別的資料型別基本函式 常用 begin 返回指向第乙個元素的迭代器 end 返回指向最後乙個元素的迭代器 clear 清除所有元素 insert 在集合中插入元素 count 返回...
C STL set集合容器常見用法
set集合容器 實現了紅黑樹的平衡二叉檢索樹的資料結構,插入元素時,它會自動調整二叉樹的排列,把元素放到適當的位置,以保證每個子樹根節點鍵值大於左子樹所有節點的鍵值,小於右子樹所有節點的鍵值 常見操作 1.元素插入 insert 2.元素查詢 find 3.元素刪除 erase 下面是乙個簡單的二叉...