C++ Primer 学习笔记_6_标准模板库_set集合容器

C++ Primer 学习笔记_6_标准模板库_set集合容器

Set集合容器实现了红黑树(Red-BlackTree)的平衡二叉检索树的数据结构,在插入元素时,它会自动调整二叉树的排序,把该元素放到适当的位置。

(1)确保每个子树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的键值;

(2)另外,还得确保根节点左子树的高度与右子树的高度相等。这样,二叉树的高度最小,从而检索速度最快。

C++ Primer 学习笔记_6_标准模板库_set集合容器_第1张图片

平衡二叉检索树的检索使用中序遍历算法,检索效率高。默认情况下,将键值由小到大遍历。

对于set容器中的键值,不可直接去修改。因为如果把容器中的一个键值修改了,set容器会根据新的键值旋转子树,这样修改的键值很可能就不在原先那个位置上了。

 

1、创建set集合对象,元素的插入与中序遍历

       采用insert()方法把元素插入集合中,默认情况下,将键值由小到大插入。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <set>
 
using namespace std;
 
int main()
{
   set<int> str;
   //插入了5个元素;但由于8有重复,第二次插入的8并没有执行
   str.insert(8); //第一次插入8,可以插入
   str.insert(1);
   str.insert(12);
   str.insert(6);
   str.insert(8); //第二次插入8,不会插入
 
   //中序遍历集合中所有的元素
   for(set<int>::iterator iter = str.begin(); iter!= str.end();iter++)
       cout << *iter << " ";
   cout << endl;
   return 0;
}

运行结果:

1 6  8  12

 

2、元素的反向遍历

       使用反向迭代器reverse_iterator可以反向遍历集合。它需要用到rbegin()和rend()两个方法,分别给出反向遍历的开始位置和结束位置。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <set>
 
using namespace std;
 
int main()
{
   set<int> str;
   //插入了5个元素;但由于8有重复,第二次插入的8并没有执行
   str.insert(8); //第一次插入8,可以插入
   str.insert(1);
   str.insert(12);
   str.insert(6);
   str.insert(8); //第二次插入8,不会插入
 
   //中序遍历集合中所有的元素
   for(set<int>::reverse_iterator iter = str.rbegin(); iter!=str.rend(); iter++)
       cout << *iter << " ";
   cout << endl;
   return 0;
}

运行结果:

12 8  6  1

 

3、元素的删除

       集合set具有高效的删除处理功能,并自动重新调整内部的红黑树的平衡。

       删除某个键值的元素用erase()方法,清空集合用clear()方法。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <set>
 
using namespace std;
 
int main()
{
    set<int> str;
    //插入了5个元素;但由于8有重复,第二次插入的8并没有执行
    str.insert(8); //第一次插入8,可以插入
    str.insert(1);
    str.insert(12);
    str.insert(6);
    str.insert(8); //第二次插入8,不会插入
 
    //删除键值为6的那个元素
    str.erase(6);
 
    //中序遍历集合中所有的元素
    for(set<int>::iterator iter = str.begin(); iter!=str.end(); iter++)
        cout << *iter <<"";
    cout << endl;
 
    //清空集合
    str.clear();
    cout << str.size()<< endl;
    return 0;
}

运行结果:

8  12

0

 

4、元素的检索

       使用find()方法对集合进行搜索,如果找到键值,返回该键值迭代器的位置。否则,返回end()。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <set>
 
using namespace std;
 
int main()
{
    set<int> str;
    //插入了5个元素;但由于8有重复,第二次插入的8并没有执行
    str.insert(8); //第一次插入8,可以插入
    str.insert(1);
    str.insert(12);
    str.insert(6);
    str.insert(8); //第二次插入8,不会插入
 
    set<int>::iterator iter = str.find(6);
    if(iter != str.end())
       cout << "找到的值为: " << *iter<< endl;
    else
       cout << "没有找到" << endl;
   
    iter = str.find(20);
    if(iter != str.end())
       cout << *iter <<endl;
    else
       cout << "没有找到" << endl;
    return 0;
}

运行结果:

找到的值为:6

没有找到

 

5、自定义比较函数

默认情况下,按照键值由小到大的顺序插入元素。由于内部数据结构都是红黑树。编写方法有两种,

(1)如果元素不是结构体,那么可以编写比较函数。下面实现键值由大道小的顺序将元素插入set中:

#include <iostream>
#include <stdio.h>
#include <vector>
#include <set>
 
using namespace std;
 
struct myComp
{
    bool operator()(int a, int b)
    {
       return a > b;
    }
};
 
int main()
{
    set<int, myComp> str;
    //插入了5个元素;但由于8有重复,第二次插入的8并没有执行
    str.insert(8); //第一次插入8,可以插入
    str.insert(1);
    str.insert(12);
    str.insert(6);
    str.insert(8); //第二次插入8,不会插入
 
    for(set<int, myComp>::iterator iter = str.begin(); iter !=str.end(); iter++)
       cout << *iter << " ";
    cout << endl;
    return 0;
}

运行结果:

12 8 6 1

 

(2)如果元素是结构体,那么,可以直接把比较函数写在结构体里面。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <set>
 
using namespace std;
 
struct Info
{
   string name;
   float score;
   bool operator < (Info a) const
    {
       //按score由大到小排列。如果要由小到大排列,使用">"号即可。
       return a.score < score;
    }
};
 
int main()
{
   set<Info> str;
   Info info;
 
   info.name = "Jack";
   info.score = 80.5;
   str.insert(info);
 
   info.name = "Tomi";
   info.score = 20.5;
   str.insert(info);
 
   info.name = "Nacy";
   info.score = 60.5;
   str.insert(info);
 
   for(set<Info>::iterator iter = str.begin(); iter != str.end();iter++)
       cout << (*iter).name << " : " <<(*iter).score << endl;
   return 0;
}


运行结果:

Jack : 80.5

Nacy : 60.5

Tomi : 20.5

 

你可能感兴趣的:(C++,STL)