标准模板库的关联容器类的惠普实现是基于红黑树类(rb_tree)的。
在一个关联容器中,项通过和其他项的比较确定它在容器中的位置。因此没有push_back()、pop_back()、push_front() 和 pop_front()方法。
红黑树(rb_tree):
红黑树是一个折半查找树,它或者为空,或者根项着黑色,而其他的每个项着红色或黑色。并满足下面的属性:
1)红色规则:如果某项着红色,那么它的父亲必须是黑色的;
2)路径规则:从根项到没有子女或有一个子女的项的所有路径上的黑色项的数量必须是相同的。
下面是rb_tree类定义的开头:
template <class Key, // 键
class Value, // 值
class KeyOfValue, // 函数类类型:从Value中返回Key
class Compare> // 函数类类型:用于Key的比较
class rb_tree
{
protected:
bool insert_always; // set和map设置为false,multiset和multimap设置为true.
};
a) set 和 multiset类中,key和Value是相同的。例如 Key 和 Value 均为 (”Ford");
b) map 和 multiset 类中,Value是一个对,它的第一个组件是 Key。例如 Key 为 (“Ford"), 而Value 为 (”Ford", 14);
c) set 和 map 类中,插入一个值(Value),它的键(Key) 和容器中某些已有值的键相同,这是非法的。而 multiset 和 multimap 中这是允许的。
d) 插入操作声明:pair<iterator, bool> insert(const value_type& value);
d) 插入操作声明:pair<iterator, bool> insert(const value_type& value);
使用了pair模板类,SLT中pair模板类部分声明如下:
template <class T1, class T2>
sturct pair
{
T1 first;
T2 second;
};
pair将2个数据组合成一个数据,当需要这样的需求时就可以使用pair。例如一个函数需要返回2个数据的时候,可以选择pair。
set:
set类声明的开头:
template <class Key, class Compare = less<Key>,
class Allocator = allocator<Key>>
class set
{};
部分接口:
iterator find(const key_type& x) const;
void erase(iterator position);
// 如果项 x 已经出现在集合中,那么返回的对就由一个位于此插入项前的迭代器和false组成。
// 否则,返回的对就由一个位于新插入项的迭代器和true组成。
pair<iterator, bool> insert(const value_type& x);
实例:
#include <iostream>
#include <string>
#include <set>
using namespace std;
int main()
{
typedef set<int> my_set;
// 等同于 typedef set<int, less<int>> my_set; (从小到大的顺序)
const int SIZE = 8;
int data[SIZE] = {5, 3, 9, 3, 7, 2, 9, 3};
cout << ">>>set:\n";
my_set s;
my_set::iterator itr1;
for (int i = 0; i < SIZE; i++){
pair<my_set::iterator, bool> p = s.insert(data[i]);
if (!p.second)
cout << data[i] << "is already in the set.\n";
}
cout << endl << "Here are the items in the set:\n";
for (itr1 = s.begin(); itr1 != s.end(); itr1++)
cout << *itr1 << endl;
cout << "Please press the Enter key to close this output window.\n";
return 0;
}
引申:
不使用缺省情况,使用用户声明的函数类。
头文件 greater.h:(声明函数类)
#ifndef _GRE_ATER_
#define _GRE_ATER_
template <class T>
struct greater
{
bool operator()(const T& x, const T& y)
{
return x > y;
}
};
#endif
上述实例修改为:
#include <iostream>
#include <string>
#include <set>
#include "greater.h"
using namespace std;
int main()
{
typedef set<int,greater<int>> my_set;// 从大到小顺序
const int SIZE = 8;
int data[SIZE] = {5, 3, 9, 3, 7, 2, 9, 3};
cout << ">>>set:\n";
my_set s;
my_set::iterator itr1;
for (int i = 0; i < SIZE; i++){
pair<my_set::iterator, bool> p = s.insert(data[i]);
if (!p.second)
cout << data[i] << "is already in the set.\n";
}
cout << endl << "Here are the items in the set:\n";
for (itr1 = s.begin(); itr1 != s.end(); itr1++)
cout << *itr1 << endl;
cout << "Please press the Enter key to close this output window.\n";
return 0;
}
multiset:
部分接口:
iterator find(const key_type& x) const;
void erase(iterator position);
iterator insert(const value_type& x);
// 返回位于第一个不破坏多集合顺序且能够插入的位置上的迭代器
iterator lower_bound(const T& x) const;
// 返回位于最后一个不破坏多集合顺序且能够插入的位置上的迭代器
iterator upper_bound(const T& x) const;
// 返回一对分别位于给定项的第一个和最后一个这样位置上的迭代器
pair<iterator, iterator> equal_range(const T& x) const;
实例:
#include <iostream>
#include <string>
#include <set>
using namespace std;
int main()
{
const int SIZE = 8;
int data[SIZE] = {5, 3, 9, 3, 7, 2, 9, 3};
cout << ">>>multiset:\n";
typedef multiset<int> my_multiset;
typedef pair<my_multiset::iterator, my_multiset::iterator> Range;
my_multiset m;
my_multiset::iterator itr2;
for (int i = 0; i < SIZE; i++)
m.insert(data[i]);
cout << "Here are the items in the set:\n";
for (itr2 = m.begin(); itr2 != m.end(); itr2++)
cout << *itr2 << endl;
cout << "find 3-Value in the multiset:\n";
Range result = m.equal_range(3);
for (itr2 = result.first; itr2 != result.second; itr2++)
cout << *itr2 << endl;
cout << "find 9-Value in the multiset:\n";
// 此处的 lower_bound(9) 可由 find(9) 替代
for (itr2 = m.lower_bound(9); itr2 != m.upper_bound(9); itr2++)
cout << *itr2 << endl;
cout << "Please press the Enter key to close this output window.\n";
return 0;
}