/*
*
********************************************
* set集合容器的基礎說明:
********************************************
*
* set集合容器使用RB-Tree的平衡二叉檢索樹的資料結構,不允許插入重複索引值
* 每個子樹根節點的索引值大於左子樹所有節點的索引值,而小於右子樹所有節點的所有索引值
* 插入過程中要進行平衡處理,但檢索過程效率高
*
* 提供了元素插入、刪除、檢索的功能
* Unique Sorted Associative Container Simple Associative Container
*
* 使用set必須使用宏語句#include <set>
*
**************************************************************************************
*
* 建立set對象:
* 1.set<int> a;
* 2.set(const key_compare& comp) //指定一個比較函數對象comp來建立set對象
*
* srtuct strLess{
* bool operator()(const char* s1,const char* s2) const{
* return strcmp(s1,s2)<0;
* }
* };
* set<const char*,strLess> s(strLess());
*
* 3.set(const set&); //set<int> b(a);
* 4.set(first,last); //set<char> c(a.begin(),a.end())
* 5.set(first,last,const key_compare& comp);
**************************************************************************************
*
* 元素的插入 //不允許插入重複索引值
* pair<iterator,bool> insert(const value_type& v); //可用於判斷是否重複插入元素,對於特殊的資訊可以提供這樣的判斷
* iterator insert(iterator pos,const value_type& v);
* void insert(first,last);
*
**************************************************************************************
*
* 元素的刪除
* void erase(iterator pos);
* size_type erase(const key_type& k); //刪除等於索引值k的元素
* void erase(first,last); //刪除[first,last)區間的元素
* void clear();
*
**************************************************************************************
*
* 訪問與搜尋
*
* iterator begin();iterator end();
* reverse_iterator rbegin();reverse_iterator rend();
*
* iterator find(const key_type& k) const;
*
* 其它常用函數
* bool empty() const;
* size_type size() const;
* void swap();
*
* //下面三個函數還沒找到合適的例子,故不做說明
* iterator lower_bound();iterator upper_bound();pair<iterator,iterator> equal_range();//上界、下屆、確定區間
*
*
*
********************************************
** cumirror ** tongjinooo@163.com ** **
********************************************
*
*/
#include <set>
#include <iostream>
//自訂資料的插入
struct student{
char name[20];
int age;
char city[20];
char phone[20];
bool operator()(const student& a,const student& b) const{
return strcmp(a.name,b.name)<0;
}
};
int main(){
using namespace std;
set<int> a;
a.insert(10);
a.insert(19);
a.insert(8);
a.insert(102);
a.insert(1);
pair<set<int>::iterator, bool> p=a.insert(18);
if(p.second){
cout<<"插入的新元素為:"<<*(p.first)<<endl;
}
else{
cout<<"已存在該元素,重複插入"<<endl;
}
set<int>::iterator i=a.find(8);
// *i=250; //與侯捷STL源碼剖析237頁所述有出入
cout<<*i<<endl; //原文為:企圖通過迭代器改變元素是不被允許的
// a.insert(251); //但VC6.0編譯運行沒有問題,只是set中的排序不正確了
//即使重新插入251,因沒有違反紅/黑樹狀結構標準,錯誤不被修正
//是否是因為STL版本問題:換STLport後編譯果然報錯
//vc6.0中的STL庫存在一定問題,大家注意
cout<<"元素訪問:"<<endl;
for(set<int>::iterator j=a.begin();j!=a.end();j++){
cout<<*j<<endl;
}
// 為何稱為容器,我認為在於對於使用者自訂資料的包容,故寫如下例子進行測實驗證
// 也可以嘗試用age作為判斷條件
student stu1={"童進",23,"武漢","XXX"};
student stu2={"老大",28,"武漢","XXX"}; //老大,你成熟了5歲,哈哈
student stu3={"餃子",23,"武漢","XXX"};
set<student,student> b(student());
b.insert(stu1);
b.insert(stu2);
b.insert(stu3);
student stu4={"餃子123",88,"福州","XXX"};
pair<set<student,student>::iterator,bool> query=b.insert(stu4);
if(query.second==false) //query.first返回插入元素的迭代器;query.second代表插入是否成功,true成功:false失敗
cout<<"重複元素插入會失敗"<<endl;
cout<<query.first->name<<endl;
for(set<student,student>::iterator k=b.begin();k!=b.end();k++){
cout<<k->name<<endl;
}
// student test1={"老大",23,"武漢","XXX"}; //這樣的元素,可以找到
// set<student,student>::iterator v=b.find(test1);
// student test2={"",23,"武漢","XXX"}; //無法找到
// set<student,student>::iterator v=b.find(test2);
student test3={"老大",99,"",""}; //可以找到,推測:
set<student,student>::iterator v=b.find(test3); //1.索引值的設定依據key_compare()函數中的設定
cout<<v->age<<endl; //2.索引值直接為定義資料類型中的第一個元素
//結論:推測1正確。
//可以修改operator()函數進行驗證,也可以看後續multiset中的例子
return 0;
}