关于STL内的比较函数



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);


该模板可以用来将区间[first,lasr)进行从小到大的排序。要求first、last 能够随机访问迭代器。元素比较是用“<"进行的,如果 “a < b"的值为true,则a 排在b 的前面;如果 “a < b"的值为false,则未必b就要排在a前面,还有看看“b < a”是否成立,成立的话b才排在a的前面。


第二个版本原型如下:
template
void sort(_RandIt first,_RandIt,last, Pred op);


这个版本和第一个版本的差别在于,元素a,b比较大小是通过表达式op(a,b)实现的,如果该表达式值为true,则a比b小;如果该表达式的值为false,也不能认为b 就比a 小,还要再看“op(b,a)"。这里的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的元素,必须是能够用<元素运算符进行比较的,而且priority_queue保证以下条件总是成立的:对于队头的元素x和任意非队头的元素y,表达式“x < y"值必为false。

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 
  void make_heap (RandomAccessIterator first, RandomAccessIterator last);
custom (2)
template 
  void make_heap (RandomAccessIterator first, RandomAccessIterator last,
                  Compare comp );
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// range heap example
#include      // std::cout
#include     // std::make_heap, std::pop_heap, std::push_heap, std::sort_heap
#include        // std::vector

int main () {
  int myints[] = {10,20,30,5,15};
  std::vector v(myints,myints+5);

  std::make_heap (v.begin(),v.end());
  std::cout << "initial max heap   : " << v.front() << '\n';

  std::pop_heap (v.begin(),v.end()); v.pop_back();
  std::cout << "max heap after pop : " << v.front() << '\n';

  v.push_back(99); std::push_heap (v.begin(),v.end());
  std::cout << "max heap after push: " << v.front() << '\n';

  std::sort_heap (v.begin(),v.end());

  std::cout << "final sorted range :";
  for (unsigned i=0; i

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是一样的



你可能感兴趣的:(数据结构与算法,数据结构与算法,STL,堆,比较)