C++ STL标准模板库---set/multiset的概念以及简单使用

2019/8/19
天气:多云

set/multiset容器基本概念

set容器基本概念

Set的特性:所有元素都会根据元素的键值自动被排序。Set的元素不像map那样可以同时拥有实值和键值,set的元素即是键值又是实值。Set不允许两个元素有相同的键值。不能通过迭代器改变set元素,set的iterator是一种const_iterator.

set拥有和list某些相同的性质,当对容器中的元素进行插入操作或者删除操作的时候,操作之前所有的迭代器,在操作完成之后依然有效,被删除的那个元素的迭代器必然是一个例外。

multiset容器基本概念

multiset特性及用法和set完全相同,唯一的差别在于它允许键值重复。set和multiset的底层实现是红黑树,红黑树为平衡二叉树的一种。

树的简单知识
二叉树就是任何节点最多只允许有两个字节点。分别是左子结点和右子节点。

二叉树示意图
C++ STL标准模板库---set/multiset的概念以及简单使用_第1张图片
二叉搜索树,是指二叉树中的节点按照一定的规则进行排序,使得对二叉树中元素访问更加高效。二叉搜索树的放置规则是:任何节点的元素值一定大于其左子树中的每一个节点的元素值,并且小于其右子树的值。因此从根节点一直向左走,一直到无路可走,即得到最小值,一直向右走,直至无路可走,可得到最大值。那么在儿茶搜索树中找到最大元素和最小元素是非常简单的事情。下图为二叉搜索树:

C++ STL标准模板库---set/multiset的概念以及简单使用_第2张图片
上面我们介绍了二叉搜索树,那么当一个二叉搜索树的左子树和右子树不平衡的时候,那么搜索依据上图表示,搜索9所花费的时间要比搜索17所花费的时间要多,由于我们的输入或者经过我们插入或者删除操作,二叉树失去平衡,造成搜索效率降低。
所以我们有了一个平衡二叉树的概念,所谓的平衡不是指的完全平衡。

C++ STL标准模板库---set/multiset的概念以及简单使用_第3张图片
RB-tree(红黑树)为二叉树的一种。

set常用API

set构造函数

set<T> st;//set默认构造函数:
mulitset<T> mst; //multiset默认构造函数: 
set(const set &st);//拷贝构造函数

set赋值操作

set& operator=(const set &st);//重载等号操作符
swap(st);//交换两个集合容器

set大小操作

size();//返回容器中元素的数目
empty();//判断容器是否为空

set插入和删除操作

insert(elem);//在容器中插入元素。
clear();//清除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(elem);//删除容器中值为elem的元素。

set查找操作

find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key);//查找键key的元素个数
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。

示例代码

#include "stdafx.h"
#include 
#include 
#include 
#include 

using namespace std;

void f_setTest01()
{
	//构造函数
	set<int>st1;
	multiset<int>mst;
	set<int>st(st1);

	//赋值操作
	st = st1;
	st.swap(st1); 

	//set大小操作
	int size = st.size();
	st.empty();

	//插入和删除操作
	st.insert(100);
	st.insert(200);
	st.insert(300);
	st.insert(400);
	st.insert(500);
	set<int>::iterator it1 = st.erase(st.begin());
	st.erase(++st.begin(), --st.end());
	st.erase(100);
	//st.clear();

	//查找操作
	set<int>::iterator it2 = st.find(500);
	int cot = st.count(500);
	set<int>::iterator it3 = st.lower_bound(500);
	set<int>::iterator it4 = st.upper_bound(500);
	pair<set<int>::iterator, set<int>::iterator> range;
	range = st.equal_range(500);
}

void f_setTest02()
{
	set<int>s;
	pair<set<int>::iterator, bool>ret = s.insert(100);
	if (ret.second)
	{
		cout << "插入成功" << endl;
	}
	else
	{
		cout << "插入失败" << endl;
	}
}

struct MyCompare
{
	bool operator()(int v1,int v2)
	{
		return v1 > v2; 
	}
};
void f_setTest03()
{
	srand((unsigned int)time(NULL));
	set<int, MyCompare>s;        //set容器的第二个参数模板可以设置排序规则 默认规则是从小到大
	for (int i = 0; i < 10; i++)
	{
		s.insert(rand() % 100);
	}

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

}

class Person
{
public:
	Person(string name,int age)
	{
		this->nName = name;
		this->mAge = age;
	}
public:
	string nName;
	int mAge;
};

struct MyCompare02
{
	bool operator()(const Person&p1,const Person &p2)
	{
		return p1.mAge > p2.mAge;
	}
};

void f_setTest04()
{
	set<Person, MyCompare02>s;
	Person p1("aaa",20);
	Person p2("bbb",30);
	Person p3("ccc",40);
	Person p4("ddd",50);

	s.insert(p1);
	s.insert(p2);
	s.insert(p3);
	s.insert(p4);

	for (set<Person, MyCompare02>::iterator it = s.begin();it != s.end();it++)
	{
		cout << "Name" << it->nName << "  Age" << it->mAge << endl;
	}

}

void f_pairTest()
{
	//方法1:创建一个对组
	pair<string, int>pair1(string("aaa"),20);
	cout << pair1.first << pair1.second<< endl;

	//方法2:make_pair
	pair<string, int>pair2 = make_pair("bbb",30);
	cout << pair2.first << pair2.second << endl;

	//方法3:pair = 赋值
	pair<string, int>pair3 = pair2;
	cout << pair3.first << pair3.second << endl;

}

/*
	extends the container by inserting new elements,effectively increasing the container size by the number of elements inserted
	扩展容器插入新元素,有效地增加容器大小插入的元素数量
	
	because elements in a set are unique,the insertion operation checks whether each inserted element is equivalent to an element already in the container,and if so,the element is not inserted,returning an iterator to this existing element(if the function returns a value)
	因为在一组元素是独一无二的,插入操作检查是否每个插入的元素已经相当于一个元素的容器,如果是这样,不是插入的元素,返回一个迭代器现有的元素(如果函数返回一个值)
	
*/
int _tmain(int argc, _TCHAR* argv[])
{
	//f_setTest01();
	//f_setTest02();
	//f_setTest03();
	//f_setTest04();
	f_pairTest();
	system("pause");
	return 0;
}


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