zoukankan      html  css  js  c++  java
  • C++STL排序算法

    在介绍排序算法前,先说明一个可以称为排序准则的东西,也就是定义strict weak ordering,其意义如下:

    1.必须是非对称的,对operator < 而言,如果x<y是true,则y<x为false。对判断式op()而言,若op(x,y)为true,则op(x,y)为false。

    2.必须是可传递的,对operator < 而言,如果x<y是true且y<z为true,则x<z为true。对判断式op()而言,若op(x,y)为true且op(y,z)为true。

    op(x,z)为true。

    3.必须是非自反的,对operator < 而言,x<x永远是false。对判断式op()而言,op(x,x)永远为false。

    4.必须具有等效传递性,大致上来说就是如果a==b&&b==c,那么a=c。

    STL的排序算法

    stl提供了几种算法来对区间内的元素排序,一般分为完全排序(full sorting)和局部排序(partial sorting)。在可以达到使用目的的情况下,优先使用后者,因为其效能更高。但由于一些关联式容器(set,map)和无序容器等不提供random-access iterator,所以不适用于这些排序算法。

    但值得注意的是,对全体元素进行一次性排序通常比”始终维护它们保持排序状态“效率要高,所以具体使用何种容器还要看你所需要的是什么。

    排序算法头文件

    #include<algorithm>

    1.完全排序

    void
    sort(random_access_iterator_beg,random_access_iterator_end)
    void
    sort(random_access_iterator_beg,random_access_iterator_end,binary_predicate op)
    void
    stable_sort(random_access_iterator_beg,random_access_iterator_end)
    void
    stable_sort(random_access_iterator_beg,random_access_iterator_end,binary_predicate op)
    • 在这里有sort()和stable_sort(),它们默认的第一形式都是用operator < 对区间[beg,end)内的所有元素排序。
    • sort()和stable_sort()的第二形式使用binary predicate作为排序准则,也就是使用者自己去定义的排序准则。
    • 注意,op必须针对元素值定义出strict weak ordering,也就是本文开篇所介绍的内容。
    • sort()与stable_sort()的区别在于,后者更加稳定,保证相等的元素的相对次序在排序后不发生改变。

    时间复杂度:

    sort():平均复杂度nlogn,最坏n^2。

    stable_sort():若内存足够,则就是nlogn,不会变化。若没有足够内存,则复杂度是2nlogn。

    比较常用的sort结构体排序

    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct node
    {
        int num1,num2;
    }arr[10000];
    bool cmp(node a,node b)//自定义比较准则
    {
        return a.num1<b.num1;//以num1较小者优先排列
    }
    int main()
    {
        arr[0]={1,2};
        arr[1]={2,1};
        arr[2]={3,4};
        arr[3]={4,3};
        sort(arr,arr+4,cmp);//严格按照要求传入参数
        for(int i=0;i<4;++i)
        {
            cout<<arr[i].num1<<" ";
        }
        cout<<endl;
        for(int i=0;i<4;++i)
        {
            cout<<arr[i].num2<<" ";
        }
    return 0; }

     

    2.局部排序

    void
    partial_sort(random_access_iterator_beg,random_access_iterator_sortend,random_access_iterator_end)
    void
    partial_sort(random_access_iterator_beg,random_access_iterator_sortend,random_access_iterator_end,binary_predicate op)

     

    • 第一形式以operator < 对[beg,end)区间内元素进行排序,使[beg,sortend)区间内元素处于有序状态。
    • 第二形式使用binary predicate作为排序准则,也就是使用者自己去定义的排序准则。
    • 除了与sort所需要注意的相同外,partial_sort()并不对全部元素排序,你传入的参数分别是排序首部,排序尾部,整体区间尾部。它会按照你所指示的区间进行排序,不用进行多余的操作。
    • 如果sortend等于end的话,那么partial_sort()会对整个序列排序,平均而言其性能不及sort(),但最差情况则优于sort()。

    时间复杂度:在线性与nlogn之间。

    3.根据第n个元素排序

    void
    nth_element(random_access_iterator_beg,random_access_iterator_nth,random_access_iterator_end)
    void
    nth_element(random_access_iterator_beg,random_access_iterator_nth,random_access_iterator_end,binary_predicate op)

     

    两种形式都对[beg,end)区间内的元素排序,使第n个位置上的元素就位,也就是说,在位置n之前的元素都小于等于它,所有之后的元素都大于等于它。这样,你就得到了”根据n位置上的元素“分割开来的两个子序列,第一子序列的元素统统小于第二子序列的元素,但是处于无序状态。同样的,该算法也提供自定义排序准则。

    时间复杂度:平均为线性。

    nth_element操作举例

    #include<iostream>
    #include<algorithm>
    bool cmp(int a,int b)
    {
        return a>b;
    }
    using namespace std;
    int main()
    {
        int a[]={1,5,6,2,9,7,3,4,10,8};
        int elem=a[2];
        nth_element(a, a+3, a+10);//第一种形式,默认为<
        int i=0;
        while(a[i]<elem)
        {
            cout<<a[i]<<" ";
            i++;
        }
        cout<<endl;
        int b[]={1,5,6,2,9,7,3,4,10,8};
        nth_element(b,b+3,b+10,cmp);//传入重载函数
        int j=0;
        while(b[j]>elem)
        {
            cout<<b[j]<<" ";
            j++;
        }
    }

     运行结果

    由此可见虽然分割出了序列,但顺序是打乱的。

     

     

     

  • 相关阅读:
    4天精通arcgis
    性能优化紧急回顾笔记
    linux下oracle导入dmp文件
    centos虚拟机复制后网络重启出错解决
    redhat ent 6.5 virtualbox虚拟机通过桥接方式配置主机-虚拟机的局域网
    SVN的搭建及使用(三)用TortoiseSVN修改文件,添加文件,删除文件,以及如何解决冲突,重新设置用户名和密码等
    SVN 的搭建及使用(二)VisualSVN Server建立版本库,以及VisualSVN和TortoiseSVN的使用
    SVN 的搭建及使用(一)下载和搭建SVN服务器
    Visual Studio 2008常见问题
    .net 学习路线感想(转)
  • 原文地址:https://www.cnblogs.com/cloudplankroader/p/10434931.html
Copyright © 2011-2022 走看看