1. 程式人生 > >集合(set)的原理和實現簡述

集合(set)的原理和實現簡述

本文主要簡述集合的原理和實現,便於快速學習和查閱。

集合的原理

set集合容器實現了紅黑樹(Red-Black Tree)的平衡二叉檢索樹的資料結構,在插入元素時,它會自動調整二叉樹的排列,把該元素放到適當的位置,以確保每個子樹根節點的鍵值大於左子樹所有節點的鍵值,而小於右子樹所有節點的鍵值。
另外,還得確保根節點左子樹的高度與右子樹的高度相等,這樣,二叉樹的高度最小,從而檢索速度最快。
要注意的是,它不會重複插入相同鍵值的元素,而採取忽略處理。如圖是一個典型的紅黑樹。
這裡寫圖片描述
平衡二叉檢索樹的檢索使用中序遍歷演算法,中序遍歷演算法可將鍵值由小到大遍歷出來,所以,可以理解為平衡二叉檢索樹在插入元素時,就會自動將元素按鍵值由小到大的順序排列。

集合的實現
  • 標頭檔案
    運用集合時別忘了標頭檔案set
#include<set>
  • 定義
    建立集合時需要指定元素的型別。
set<Data_Type> name;

Data_Type 為集合儲存的資料的型別,name 為集合的名稱。
例如:

set<int> s;    // 命名為s的集合儲存整型資料
  • 元素插入
    運用insert() 將元素插入集合。
s.insert(Data_Type);

Data_Type 型別與宣告集合時的型別相同。
例如:

s.insert(1);

預設的比較規則下,是按元素值由小到大插入;如果自己指定了比較規則函式,則按自定義比較規則函式插入。

  • 遍歷
    begin()end() 兩個方法分別表示集合中第一個和最後一個元素。
set<int>::iterator it;  // 定義向前迭代器
for (it = s.begin(); it != s.end(); it++)  // 由第一個元素至最後一個元素
    cout << *it << endl;   // 輸出該值
  • 反向遍歷
    使用反向迭代器reverse_iterator 可以反向遍歷集合。需要使用 rbegin()rend() 兩個方法,分別給出反向遍歷的開始位置和結束位置。
set<int>::reverse_iterator rit;   // 定義反向迭代器
for (rit = rbegin(); rit != rend(); rit++) cout << *rit << endl;
  • 元素刪除
    刪除的物件可以是某個迭代器位置上的元素、等於某鍵值的元素、一個區間上的元素。
    刪除某個元素用erase()
s.erase(Data_Type);

Data_Type 為定義時集合儲存資料的型別。
例如:

s.erase(1);
  • 清空
    運用clear() 將集合中元素全部刪除。
s.clear();
  • 檢索
    使用find() 方法對集合進行檢索。如果找到該值,就返回該值迭代的位置;否則返回集合最後一個元素後一個位置,即end()
set<int>::iterator it;
it = s.find(Data_Type);