STL的关联容器中,内部的元素是排序的。STL中的许多算法,也会牵涉到排序、查找。这些容器和算法都需要对元素进行比较,有的比较是否相等,有的比较元素大小。在STL中,默认的情况是,比较大小是用“<"运算符进行的,和“>"运算符无关。
在STL中提到”大“、”小“的概念的时候,以下三个说法是等价的:
(1)x 比 y 小
(2)表达式”x < y"为真
(3)y 比 x 大
一定要注意,“y 比 x 大” 意味着 “ ”x < y"为真 ”, 而不是“ y > x 为真” 。 “y > x" 结果到底如何不重要,甚至” y > x” 是没有定义的都没关系
STL的关联容器中,内部的元素是排序的。STL中的许多算法,也会牵涉到排序、查找。这些容器和算法都需要对元素进行比较,有的比较是否相等,有的比较元素大小。在STL中,默认的情况是,比较大小是用“<"运算符进行的,和“>"运算符无关。
在STL中提到”大“、”小“的概念的时候,以下三个说法是等价的:
(1)x 比 y 小
(2)表达式”x < y"为真
(3)y 比 x 大
一定要注意,“y 比 x 大” 意味着 “ ”x < y"为真 ”, 而不是“ y > x 为真” 。 “y > x" 结果到底如何不重要,甚至” y > x” 是没有定义的都没关系
a . "x 最大" == " 找不到比x 大的元素” ,而不是“ x 比 其他元素都大”
使用STL的关联容器和许多算法时,往往需要对“<"运算符进行适当的重载,使得这些容器和算法可以用”<"对所操作的元素进行比较。最好将“<"重载为全局函数,因为在重载为成员函数时,在有些编译器上会出错。
应用1:SORT函数中的比较
sort函数有两个版本,第一个版本如下
template
void sort(_RandIt first, _RandIt last);
template
void sort(_RandIt first,_RandIt,last, Pred op);
STL中定义了一些函数对象类模板,都在头文件functional中。例如greater,其源代码如下
struct greater
{
bool operater()(const T& x,const T&y) const
{
return x > y;
}
}
假设有以下数组
int a[4] = {3,5,34,8};
要将该数组从大到小排序,则只需编写
sort(a,a+4,greater
使用greater模板,要确保”>"是本来就有定义的或经过了适当的重载。
下面是使用实例:
#include
#include
#include
using namespace std;
bool Greater1(int a1, int a2)
{
return a1 > a2;
}
bool Greater2(int a1, int a2)
{
return (a1 % 10) > (a2 % 10);
}
struct LessA
{
bool operator() (int a1, int a2)
{
return (a1 / 10) < (a2 / 10);
}
}lessA;
int main()
{
int a[5] = { 12, 423, 67, 35, 20 },i;
cout << "Original a is :";
for (i = 0; i < 5; i++)
cout << a[i] << ' ';
sort(a, a + 5);
cout << endl << "SORT1 :";
for (i = 0; i < 5; i++)
cout << a[i] << ' ';
sort(a, a + 5, Greater1); //Greater1作为函数指针,实现从大到小排序
cout << endl << "SORT2 by function pointer :";
for (i = 0; i < 5; i++)
cout << a[i] << ' ';
sort(a, a + 5, Greater2); //Greater2作为函数指针,实现按个位数从大到小排序
cout << endl << "SORT2 by function pointer :";
for (i = 0; i < 5; i++)
cout << a[i] << ' ';
sort(a, a + 5, lessA); //lessA作为函数对象,实现按十位从小到大排序
cout << endl << "SORT2 by function object :";
for (i = 0; i < 5; i++)
cout << a[i] << ' ';
sort(a, a + 5, greater()); //greater()作为函数对象,实现从大到小排序
cout << endl << "SORT2 by function template :";
for (i = 0; i < 5; i++)
cout << a[i] << ' ';
system("pause");
return 0;
}
应用2 堆的实现
STL中有stack、queue、priority_queue三种容器适配器,他们都是在顺序容器的基础上实现的,都有三个成员函数pop、push、top
priority_queue和普通队列的队头元素总是最大的,即实现了最大堆的功能。priority_queue默认的元素比较器是less
priority_queue定义如下:
template,class Compare = less >
class priority_queue
{
...
};
注意:这里的第三个参数为函数对象类,而非函数对象,故不能用函数指针实现,与上面的sort的第三个参数不同
为了实现最小堆,可以使用greater函数对象模板,也可以自己重载<运算符
注意:对于自己定义的类或结构,必须重载< 运算符,即使是只想实现最大堆
struct node{ int x,y; int door; bool operator < (const node &a) const{ return a.door<door; } };
priority_queue
heap;
priority_queue,greater > pQueue;
实际上,SLT中有make_heap、push_heap、pop_heap函数,默认生成最大堆
default (1) | template |
---|---|
custom (2) | template |
|
|
Output
initial max heap : 30 max heap after pop : 20 max heap after push: 99 final sorted range : 5 10 15 20 99其第三个参数的定义和priority_queue是一样的