set/multiset容器

一、二叉树基本概念

二叉树就是任何节点最多只允许有两个子节点。分别是左子节点和右子节点。

二叉搜索树,是指二叉树中的节点按照一定的规则进行排序,使得对二叉树中元素访问更加高效。二叉搜索树的放置规则是:任何节点的元素值一定大于其左子树中的每一个节点的元素值,并且小于右子树的值。因此从根节点一直向左走,一直到无路可走,即得到最小值,一直向右走,直到无路可走,可得到最大值。那么在二叉搜索树中找到最大元素和最小元素是非常简单的事情。

RB-tree(红黑树)为二叉树的一种。

二、set/multiset特性

set/multiset的特性是所有元素会根据元素的值自动进行排序。set以RB-tree(红黑树,平衡二叉树的一种)为底层机制,其查找效率非常好。set容器中不允许重复元素,multiset允许重复元素。

问:可以通过set的迭代器改变元素的值吗?

答:不行,因为set集合是根据元素值进行排序,关系到set的排序规则,如果任意改变set的话,会严重破坏set组织。

三、set常用API

1、set构造函数

2、set赋值操作

3、set大小操作

4、set插入和删除操作

5、set查找操作

四、案例

程序运行不成功,还未找到原因!

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <set>
using namespace std;

void PrintSet(set<int>& s)
{
    for (set<int>::iterator it = s.begin();it != s.end();it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
    //set初始化操作
    set<int> s1;
    s1.insert(7);
    s1.insert(2);
    s1.insert(4);
    s1.insert(5);
    s1.insert(1);
    
    PrintSet(s1);//1 2 4 5 7
    //自动进行排序 默认从小到大

    //赋值操作
    set<int> s2;
    s2 = s1;
    PrintSet(s2);//1 2 4 5 7

    //删除操作
    s1.erase(s1.begin());
    PrintSet(s1);//2 4 5 7
    s1.erase(7);
    PrintSet(s1);//2 4 5
}

//set查找操作
void test02()
{
    set<int> s1;
    s1.insert(7);
    s1.insert(2);
    s1.insert(4);
    s1.insert(5);
    s1.insert(1);

    set<int>::iterator ret = s1.find(14);
    if (ret == s1.end())
    {
        cout << "没有找到!" << endl;//没有找到!
    }
    else
    {
        cout << "ret:" << *ret << endl;
    }

    //找到第一个大于等于key的元素
    ret = s1.lower_bound(2);
    if (ret == s1.end())
    {
        cout << "没有找到!" << endl;
    }
    else
    {
        cout << "ret:" << *ret << endl;//ret:2
    }

    //找到第一个大于key的元素
    ret = s1.upper_bound(2);
    if (ret == s1.end())
    {
        cout << "没有找到!" << endl;
    }
    else
    {
        cout << "ret:" << *ret << endl;//ret:4
    }

    //equal_range 返回lower_bound和upper_bound的值
    pair<set<int>::iterator, set<int>::iterator> myret = s1.equal_range(2);
    if (myret.first == s1.end())
    {
        cout << "没有找到!" << endl;
    }
    else
    {
        cout << "myret:" << *(myret.first) << endl;//myret:2
    }
    if (myret.second == s1.end())
    {
        cout << "没有找到!" << endl;
    }
    else
    {
        cout << "myret:" << *(myret.second) << endl;//myret:4
    }
}
int main(void)
{
    //test01();
    test02();
    return 0;
}

 五、set容器存储对象 更改默认排序

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <set>
using namespace std;

//仿函数
class mycompare
{
public:
    bool operator()(int v1, int v2)
    {
        return v1 > v2;
    }
};

void test01()
{
    //set初始化操作
    set<int, mycompare> s1;
    s1.insert(7);
    s1.insert(2);
    s1.insert(4);
    s1.insert(5);
    s1.insert(1);

    for (set<int>::iterator it = s1.begin();it != s1.end();it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

class Person
{
public:
    Person(int age,int id):id(id),age(age){}
public:
    int id;
    int age;
};

//仿函数
class mycompare2
{
public:
    bool operator()(Person p1, Person p2)
    {
        return p1.age > p2.age;
    }
};
void test02()
{
    set<Person,mycompare2> sp;
    Person p1(10, 20), p2(30, 40), p3(50, 60);
    sp.insert(p1);
    sp.insert(p2);
    sp.insert(p3);

    Person p4(10, 30);
 
    for (set<Person, mycompare2>::iterator it = sp.begin();it != sp.end();it++)
    {
        cout << (*it).age << " " << (*it).id << endl;
    }

    //查找
    set<Person, mycompare2>::iterator ret = sp.find(p4);
    if (ret == sp.end())
    {
        cout << "没有找到!" << endl;
    }
    else
    {
        cout << "找到:" << (*ret).id << " " << (*ret).age << endl;
    }

}

int main(void)
{
    //test01();
    test02();
    return 0;
}

 

posted @ 2018-12-11 16:37  悦悦的小屋  阅读(1035)  评论(0编辑  收藏  举报