初等排序方法简介

初等排序方法

排序就是将数据按照一定的顺序重新排列。它是许多算法的基础,可以让数据变得更容易处理。

  用来排序的算法有很多种,这就关系到了算法的选取问题了。在之前我们提到过,算法选取最重要的就是算法复杂度的问题了,这在排序算法中尤为明显,如果算法太差,可能会导致排序的时间太长,造成代码执行超时的问题。因此,就更应该选取复杂度较小的算法。我在此只介绍简单入门的排序方法,告知原理,高等排序在接下来会详细讲到。

  • 插入排序
    代码如下:

    #include<iostream>
    using namespace std;
    void insertionSort(int A[],int N);
    int main()
    {
       int A[100];
       for(int i=0;i<100;i++)
           A[i]=100-i;
       for(int i=0;i<100;i++)
           cout<<A[i]<<" ";
       cout<<endl;
       insertionSort(A,100);
       for(int i=0;i<100;i++)
           cout<<A[i]<<" ";
       cout<<endl;
    }
    void insertionSort(int A[],int N)//从小到大排序。
    {
       int tmp, j;
       for(int i=1;i<N;i++){
           tmp=A[i];
           j=i-1;
           while(j>=0 && A[j]>tmp)//将所有比tmp大的元素都排到tmp后面
           {
               A[j+1]=A[j];
               j--;
           }
           A[j+1]=tmp;//在最后一次时A[j+1]被赋给了A[j+2],且出现了A[j]小于或等于tmp的情况,故将tmp付给A[j+1]。
       }
       //由于输入的是数组的首地址,故无需返回值,直接改变了数组A。
    }
    

    插入排序相对优势还是很大的,在最优情况下,插入排序仅需要从头到尾遍历一遍,无需进入while循环,复杂度只有 O ( N ) O(N) O(N),但是当恰好反序的情况下,复杂度就变成了 O ( N 2 ) O(N^2) O(N2),由此可见,输入的数据不同,算法的执行时间也会不同,但是我们一般都要考虑在最坏的情况下的算法效率,因此,插入排序只适合处理相对有序的一组数据。

  • 选择排序
    代码如下:

    #include<iostream>
    using namespace std;
    void selectionSort(int A[],int N);
    int main()
    {
       int A[100];
       for(int i=0;i<100;i++)
           A[i]=100-i;
       for(int i=0;i<100;i++)
           cout<<A[i]<<" ";
       cout<<endl;
       selectionSort(A,100);
       for(int i=0;i<100;i++)
           cout<<A[i]<<" ";
       cout<<endl;
    }
    void selectionSort(int A[],int N)//从小到大排序。
    {
       for(int i=0;i<N-1;i++)
       {
           for(int j=i+1;j<N;j++)
           {
               if(A[j]<A[i])
                   swap(A[j],A[i]);//若A[j]<A[i],则交换两者位置,从而把最小的元素提到当前循环的最前方,每次都选择最小元素,排列起来,就是从小到大的排布。
           }
       }
       //由于输入的是数组的首地址,故无需返回值,直接改变了数组A。
    }
    

    选择排序对于未排列部分也和插入排序一样算法复杂度为 O ( N 2 ) O(N^2) O(N2),也是对排序较好的部分效果较好。

  • 冒泡排序
    代码如下:

    #include<iostream>
    using namespace std;
    void bubbleSort(int A[],int N);
    int main()
    {
       int A[100];
       for(int i=0;i<100;i++)
           A[i]=100-i;
       for(int i=0;i<100;i++)
           cout<<A[i]<<" ";
       cout<<endl;
       bubbleSort(A,100);
       for(int i=0;i<100;i++)
           cout<<A[i]<<" ";
       cout<<endl;
    }
    void bubbleSort(int A[],int N)//从小到大排序。
    {
       int flag=1;
       for(int i=0;flag;i++)
       {
           flag=0;
           for(int j=N-1;j>i;j--)
           {
               if(A[j]<A[j-1])
               {
                   swap(A[j],A[j-1]);
                   flag=1;
               }//若A[j]<A[j-1],则交换两者位置,从而把较小的元素提到当前循环的最前方,每次都选择较小元素,就像泡泡一样慢慢浮到最前面,故称冒泡排序。
               //若不进入if语句,说明已经排序完成,flag=0,跳出循环。
           }
       }
       //由于输入的是数组的首地址,故无需返回值,直接改变了数组A。
    }
    

    冒泡排序对于未排列部分也和插入排序一样算法复杂度为 O ( N 2 ) O(N^2) O(N2),对排序较好的数据可以早早flag=0,从而跳出循环减少运算次数。

排序算法千千万,究其根本就是按顺序排布,但是当遇到相同的数据时又该怎么办呢?这就遇到了排序算法当中的稳定排序和不稳定排序的问题了。

  当遇到相同数据时,若排序之后不会改变原来的先后顺序,则成该排序是稳定的,反之则称该排序是不稳定的。如下表:

姓名英语
A95
B91
C91
D90

选择排序后:

姓名英语
D90
C91
B91
A95

冒泡排序后:

姓名英语
D90
B91
C91
A95

  可以发现,在选择排序后,B和C原来的顺序也交换了,而在冒泡排序中,B与C的位置却没有发生改变,还是保持原来的先后顺序。所以就可以说,选择排序是不稳定的排序,而冒泡排序是稳定的排序。

  在选择排序方法时,其实最重要的还是在于判断语句中是否有等于号,很多时候在添加上一个小小的等于号之后,原来的稳定的排序可能就会变成不稳定的排序,而且还会因此重复比较相同的元素,使得运算次数增加,甚至会产生错误。

  最后加一点,在C++标准库中是包含sort函数的,在头文件#include <algorithm>里面,此处sort函数复杂度只有 O ( n ∗ log ⁡ ( n ) ) O(n*\log(n)) O(nlog(n)),是采用了快排算法,建议使用。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值