set的底層是平衡搜索樹。
搜索樹:左邊小右邊大
搜索樹的時間複雜度是O(N)
普通搜索樹 左邊比根節點小,右邊比根節點大 O(N)
AVL樹 嚴格平衡 左右高度差不超過1 O(logN)
- 紅黑樹 近似平衡 最長路徑不超過最短路徑的2倍 O(2logN)
- 根節點是黑色的
- 沒有連續的紅節點
- 每條路徑上的黑節點的數量相等
N特別大的時候AVL和紅黑樹搜索次數相差不大。
set
set的插入
void Test()
{
set<int> s1;
s1.insert(3);
s1.insert(1);
s1.insert(2);
s1.insert(2);
}
set的遍歷
// 正向迭代器, 排序加去重
set<int>::iterator it1 = s1.begin();
while(it1 != s1.end())
{
cout<<*it1<<" ";
++it1;
}
cout<<endl;
//反向迭代器
set<int>::reverse_iterator rit1 = s1.rbegin();
while(rit1 != s1.rend())
{
cout<<*rit1<<" ";
rit1++;
}
cout<<endl;
set中查找某一個值是否存在
set<int>::iterator ret = s1.find(2);
if(ret != s1.end())
{
cout<<"找到了"<<endl;
}
//算法的插入
ret = find(s1.begin(), s1.end(), 2);
if(ret != s1.end())
{
cout<<"找到了"<<endl;
}
兩種方法的差別
- 查找效率 第一種O(logN) 第二種O(N)
set的刪除
//按位置刪除,位置必須是一個有效的位置
s1.erase(ret);
//按值刪除
s1.erase(3);
set的交換
swap(s1, s2); // 結果一樣,按理來說付出的代價更大,實際上被優化了
s1.swap(s2);
multiset允許重複,只排序
multiset在查找的時候找中序的第一個。
count():求一個值得個數
注意點:
- set不允許通過迭代修改,因爲可能會破壞搜索樹的規則
- 迭代器失效