stl sort和qsort的使用

好不容易使用了下stl的qsort函数,顺便和sort函数一起总结下:

很多时候我们都需要用到排序。

 例如:
1
#include <iostream> 2 #include <algorithm> 3 4 using namespace std; 5 6 int a[5] = {2, 1, 3, 5, 6};//对这个数组排序 7 int main() 8 { 9 sort(a, a + 5); 10 for (int i = 0; i < 5; i++) 11 cout<<a[i]<<endl; 12 return 0; 13 }
可以看到,sort默认是从小到达排序的,那如何自定义排序呢。

先看看sort的函数声明:

template <class RandomAccessIterator>
  void sort (RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class Compare>
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

sort函数将[first, last]区间按升序进行排序,排序是使用值类型的<运算符进行比较。第一个版本使用<来确定顺序,也就是从大到小,

第二个版本则使用自定义的比较对象或比较函数。

现在要对a[5] = {2, 1, 3, 5, 6};进行升序。

 

#include <iostream>
#include <algorithm>

using namespace std;

int a[5] = {2, 1, 3, 5, 6};
int b[5] = {2, 1, 3, 5, 6};
bool cmp(const int a, const int b)
{
    return a > b;
}
class cmpClass
{
public:
    bool operator () (const int a, const int b)
    {
        return a > b;
    }
};
struct cmpStruct/**< 使用类似cmpClass */
{
    bool operator () (const int a, const int b)/**< 自定义比较对象需要重载()才行 */
    {
        return a > b;
    }
};
int main()
{
    sort(a, a + 5, cmp);/**< 使用自定义函数 */
    cout<<"a[]:";
    for (int i = 0; i < 5; i++)
        cout<<' '<<a[i];
    cout<<endl;
    cmpClass a;/**< 先声明个对象 */
    sort(b, b + 5, a);/**< 使用比较对象 */
    cout<<"b[]:";
    for (int i = 0; i < 5; i++)
        cout<<' '<<b[i];
    cout<<endl;
    return 0;
}
运行结果:
a[]: 6 5 3 2 1
b[]: 6 5 3 2 1

对于自定义类型也可以使用sort,但必须提供比较函数。
例如

#include <iostream>
#include <algorithm>

using namespace std;
struct point
{
    int x, y;
    bool operator < (const point &b)const/**<重载<号,可根据自己需要实现内部代码 */
    {
        if (x == b.x)
            return y < b.y;
        return x < b.x;
    }
};
point p[5] =
{
    1, 2,
    1, 1,
    4, 8,
    2, 3,
    4, 6
};
/**< 对p数组进行排序,先按x小的,如果x相等,再按y小的排序 */
int main()
{
    sort(p, p + 5);
    cout<<"p[]:";
    for (int i = 0; i < 5; i++)
        cout<<'('<<p[i].x<<','<<p[i].y<<')';
    cout<<endl;
    return 0;
}
也可以自己用自定义的比较函数或比较对象来排序。
运行结果:
p[]:(1,1)(1,2)(2,3)(4,6)(4,8)

下面就来讲讲qsort函数

/**< 对于下面的a数组,如何使用qsort来排序呢,先看看代码实现 */
#include <iostream>
#include <algorithm>

using namespace std;

int a[5] = {2, 1, 3, 5, 6};
int cmp(const void *a, const void *b)/**< 从小到大排序 */
{
    return ((*(int *)a) - (*(int *)b);
}
int main()
{
    qsort(a, 5, sizeof(a[0]), cmp);
    cout<<"a[]:";
    for (int i = 0; i < 5; i++)
        cout<<' '<<a[i];
    return 0;
}
运行结果:
a[]: 1 2 3 5 6

对于整数和字符类型可以直接返回差值,
但对于实数需要注意,因为比较函数返回的是int类型。
例如:

#include <iostream>
#include <algorithm>

using namespace std;

double a[5] = {2.4, 1.5, 3.4, 5.5, 1.6};
int cmp(const void *a, const void *b)/**< 从小到大排序 */
{
    return (*(double *)a) > (*(double *)b) ? 1 : -1;
}
int main()
{
    qsort(a, 5, sizeof(a[0]), cmp);
    cout<<"a[]:";
    for (int i = 0; i < 5; i++)
        cout<<' '<<a[i];
    return 0;
}
运行结果:
a[]: 1.5 1.6 2.4 3.4 5.5

还是先来看看qsort函数原型
_CRTIMP void __cdecl qsort(void*, size_t, size_t, int (*)(const void*, const void*));
对于为何要那样定义比较函数应该有个大概明白了吧。
原型要与int (*)(const void*, const void*)(函数指针的应用)对应。

qsort也可对自定义类型排序

#include <iostream>
#include <algorithm>

using namespace std;
struct point
{
    int x, y;
};
point p[5] =
{
    1, 2,
    1, 1,
    4, 8,
    2, 3,
    4, 6
};

int cmp(const void *a, const void *b)
{
    point *pa = (point *)a;
    point *pb = (point *)b;
    if (pa->x == pb->y)
        return pa->y - pb->y;
    return pa->x - pb->y;
}
/**< 对p数组进行排序,先按x小的,如果x相等,再按y小的排序 */
int main()
{
    qsort(p, 5, sizeof(p[0]), cmp);
    cout<<"p[]:";
    for (int i = 0; i < 5; i++)
        cout<<'('<<p[i].x<<','<<p[i].y<<')';
    cout<<endl;
    return 0;
}
运行结果:
p[]:(1,1)(1,2)(2,3)(4,6)(4,8)


对于其它自定义类型也是类似。

sort和qsort函数的平均时间复杂度都是NlogN,log以2为底。
都在algorithm文件里,同时别忘了使用命名空间
using namespace std。
看到这以后就不用在担心自己不会写排序函数了,学会了这两个函数,应付大部分排序就足够用了。

 

posted on 2014-04-21 00:00  jec  阅读(338)  评论(0编辑  收藏  举报

导航