浅谈C/C++排序函数中cmp()比较函数的写法(qsort sort函数)

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-31 23:06   39   0

转自 http://blog.csdn.net/lionel_d/article/details/41746135

首先,我们来谈谈大名鼎鼎的void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const void *));

它属于C语言标准库函数,应该是运用最多的了,今天我不是来教你们怎么用qsort的,只是来交流一下排序函数的最后一个参数cmp()(它不仅可以叫cmp,你还可以给他取名叫什么pig啊dog的只要是英文单词都可以,cmp只是人们对compare的一种常用缩写)比较函数的写法。

下面是cmp的写法:

  1. int cmp(const void *a ,const void *b)
  2. {
  3. return *(int *)a - *(int *)b ; //从小到大排序,把a,b位置反过来就是从大到小
  4. }


注意:qsort的cmp()函数千万别写成下面这样

  1. //错错错错错错错 错错错错错错错 错错错错错错错 错错错错错错错
  2. int cmp(const void *a ,const void *b)
  3. {
  4. return *(int *)a > *(int *)b ; // > 与 < 都不行 !
  5. }
  6. //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


有一次就是写了下面的cmp(),结果排序死活不对!


下面是完整的测试代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int cmp(const void *a ,const void *b)
  4. {
  5. return *(int *)a - *(int *)b ; //从小到大排序,把a,b位置反过来就是从大到小, 要加上*号
  6. }
  7. int main()
  8. {
  9. int a[10]={-1,9,5,7,-11,2,6,8,9,6};
  10. qsort(a,10,sizeof(int),cmp);
  11. for(int i = 0 ; i < 10 ; ++i)
  12. {
  13. printf("%d ",a[i]);
  14. }
  15. printf("\n") ;
  16. return 0 ;
  17. }

测试结果:






第二个cmp(),就是void sort( iterator start, iterator end, StrictWeakOrdering cmp );下面是标准声明:

  template <class RandomAccessIterator, class Compare>
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
他的头文件是<algorithm>,这个是标准C++头文件里的。

  1. bool cmp(int a ,int b)
  2. {
  3. return a < b ; //从小到大排序,把 < 换成 > 就是从大到小
  4. }

好的,问题又来了,这个cmp与qsort的cmp不一样了,正好相反,他不能写成下面这样:

  1. //错错错错错错错 错错错错错错错 错错错错错错错 错错错错错错错
  2. bool cmp(int a ,int b)
  3. {
  4. return a - b ;
  5. }
  6. //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


切记,切记!

下面是sort的测试代码:

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std ;
  4. bool cmp(int a ,int b)
  5. {
  6. return a < b ; //从小到大排序,把 < 换成 > 就是从大到小
  7. }
  8. int main()
  9. {
  10. int a[10]={-1,9,5,7,-11,2,6,8,9,6};
  11. sort(a,a+10,cmp);
  12. for(int i = 0 ; i < 10 ; ++i)
  13. {
  14. cout<<a[i]<<" " ;
  15. }
  16. cout<<endl ;
  17. return 0 ;
  18. }

测试结果:




在C++中,我们经常需要用到set,map等容器,他们的cmp基本写法都与sort的相同,当然set,map的cmp可不仅仅是函数了,而是函数对象:

  1. struct cmp{
  2. bool operator ()(const int a , const int b)
  3. {
  4. return a < b ; // 从小到大,反过来就是从大到小
  5. }
  6. };

下面仅仅对set做代码测试:

  1. #include <iostream>
  2. #include <cstring>
  3. #include <set>
  4. using namespace std ;
  5. struct Person{
  6. int age;
  7. char name[20];
  8. Person(int Age , const char Name[]):age(Age){strcpy(name,Name);}
  9. };
  10. struct cmp{
  11. bool operator ()(const Person a , const Person b)
  12. {
  13. return a.age < b.age ; // 从小到大 ;
  14. }
  15. };
  16. int main()
  17. {
  18. set<Person,cmp> s ;
  19. Person n1(46,"ggg");
  20. Person n2(-16,"fff"); //年龄无负数,只是为了测试代码,下同
  21. Person n3(45,"eee");
  22. Person n4(-25,"ddd");
  23. Person n5(34,"ccc");
  24. Person n6(22,"bbb");
  25. Person n7(2,"aaa");
  26. s.insert(n1);
  27. s.insert(n2);
  28. s.insert(n3);
  29. s.insert(n4);
  30. s.insert(n5);
  31. s.insert(n6);
  32. s.insert(n7);
  33. set<Person,cmp>::iterator begin = s.begin();
  34. set<Person,cmp>::iterator end = s.end();
  35. for(set<Person,cmp>::iterator i = begin ; i != end ; ++i)
  36. {
  37. cout<<i->age<<" "<<i->name<<endl ;
  38. }
  39. return 0 ;
  40. }

测试结果:

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP