STL标准模板库之set

1、关联式容器

关联式容器依据特定的排序准则,自动为其元素排序。排序准则以函数形式呈现,用来比较元素值(value)或元素键(key)。缺省状况下以operator<进行 比较,不过你也能够提供本身的比较函数,定义出不一样的排序准则。数组

一般关联式容器由二叉树(binary tree)实现。在二叉树中,每一个元素(节 点)都有一个父节点和两个子节点;左子树的全部元素都比本身小,右子树的全部元素都比本身大。关联式容器的差异主要在于元素的类型以及处理重复元素时的方式。数据结构

STL预先定义好的关联式容器有:集合(set)、多重集合(multiset)、映射(map)和多重映射(multimap)。函数

2、什么是set?

集合(set)简而言之是一种包含已排序对象的关联容器,不容许有重复元素。指针

一个集合经过一个链表来组织,在插入操做和删除操做上比向量(vector)快,但查找或添加末尾的元素时会有些慢。具体实现采用了红黑树的平衡二叉树的数据结构。code

特色

  • set中的元素都是排好序的。
  • set中没有重复的元素。
  • map和set的插入删除效率比用其余序列容器高,由于对于关联容器来讲,不须要作内存拷贝和内存移动。

优缺点和适用场景:

优势:使用平衡二叉树实现,便于元素查找,且保持了元素的惟一性,以及能自动排序。对象

缺点:每次插入值的时候,都须要调整红黑树,效率有必定影响。
适用场景:适用于常常查找一个元素是否在某群集中且须要排序的场景。排序

3、定义及初始化

set<int> a; //定义一个int类型的集合a
set<int> b(a); //定义并用集合a初始化集合b
set<int> b(a.begin(), a.end()); //将集合a中的全部元素做为集合b的初始值
//相似的可使用数组来初始化向量:
int n[] = { 1, 2, 3, 4, 5 };
list<int> a(n, n + 5);              //将数组n的前5个元素做为集合a的初值

4、基本操做

1)容量函数

  • 容器大小:a.size();//返回a中元素个数
  • 容器最大容量:a.max_size();//预分配的内存空间与size不一样,返回a在内存中总共能够容纳的元素个数
  • 容器判空:a.empty();//空则返回true,不然返回false

2)修改函数

  • 插入函数:a.insert(x);//时间复杂度为O(log n)内存

    注意:set 在进行插入的时候是不容许有重复的键值的,若是新插入的键值与原有的键值重复,则插入无效(multiset能够重复)it

  • 删除函数:a.erase(参数);

    参数能够是元素或者迭代器,返回下一个元素的迭代器,时间复杂度为O(log n),注意在multiset中s.erase(x)会删除全部值为x的元素

set<int>::iterator it=a.begin();
a.erase(it);
a.erase(3);
  • 删除区间[first,end)的元素:a.erase(iterator first, iterator end);
  • 清空全部元素:a.clear();
  • 交换两个同类型容器的元素:a.swap(b);
set<int>st1;
st1.insert(1);
st1.insert(2);
st1.insert(3);
set<int>st2;
st1.insert(4);
st1.insert(5);
st1.insert(6);
st1.swap(st2);
//st1: 4 5 6
//st2: 1 2 3

3)迭代器

  • 开始迭代器指针:a.begin();//时间复杂度为O(1)

  • 末尾迭代器指针:a.end();

    返回集合的尾迭代器,众所周知,STL中区间都是左闭右开的,那么end()函数返回的迭代器即为指向集合中最大元素的下一个位置的迭代器,所以--s.end()才是指向集合中最大元素的迭代器,时间复杂度为O(1)

  • 指向常量的开始迭代器指针:a.cbegin(); //意思就是不能经过这个指针来修改所指的内容,但仍是能够经过其余方式修改的,并且指针也是能够移动的。

  • 指向常量的末尾迭代器指针:a.cend();

  • 反向迭代器指针,指向最后一个元素:a.rbegin();

  • 反向迭代器指针,指向第一个元素的前一个元素:a.rend();

  • 返回最后一个key<=keyElem元素的迭代器:a.lower_bound(keyElem);

  • 返回第一个key>keyElem元素的迭代器:a.upper_bound(keyElem);

//假设 st:1 2 3
    cout << "*(st.begin()): " << *(st.begin()) << endl;
    cout << "*(st.end()): " << *(--st.end()) << endl;
    cout << "*(st.cbegin()): " << *(st.cbegin()) << endl;
    cout << "*(st.cend()): " << *(--st.cend()) << endl;
    cout << "*(st.rbegin()): " << *(st.rbegin()) << endl;
    cout << "*(st.rend()): " << *(--st.rend()) << endl;
    cout << "*(st.lower_bound(2)): " << *(st.lower_bound(2)) << endl;
    cout << "*(st.upper_bound(2)): " << *(st.upper_bound(2)) << endl;
/*
*(st.begin()): 1
*(st.end()): 3
*(st.cbegin()): 1
*(st.cend()): 3
*(st.rbegin()): 3
*(st.rend()): 1
*(st.lower_bound(2)): 2
*(st.upper_bound(2)): 3
*/

4)其余函数

  • 统计键key的元素个数:a.count(key);//有则为1,无则为0

  • 查找函数:a.find(x);

    在set中查找值为x的元素,并返回指向该元素的迭代器,若不存在,返回set.end(),时间复杂度为O(log n)

5、与序列容器的不一样点

  • set 只支持默认构造函数和拷贝构造函数,没有其它重载的构造函数。
  • set 只能使用insert的两种重载函数插入,不支持push_back()和push_front()函数。
  • set 能不经过迭代器,只经过元素值来删除该元素。
  • set 容器不提供下标操做符。为了经过键从 set 中获取元素,可以使用 find 运算。
  • set 不支持STL里的reverse和sort算法。
相关文章
相关标签/搜索