O(n^2)的一般排序方法

来源:互联网 发布:买股票的软件 编辑:程序博客网 时间:2024/05/19 20:39

前言

对于现在来说,O(n^2)的排序算法用处已经不是很大了。但他们较为基础和简单,方便初学者的理解,所以还是有必要进行学习的。这里就介绍几种常用的O(n^2)的排序方法。

种类:

  1. 冒泡排序及其改进
  2. 选择排序
  3. 插入排序

先贴出一些会用的自定函数:

void Swap(int &a,int &b)//交换次序用,其实可以直接用STL里的sort来代替{    int c=a;    a=b;b=c;}void print(int *a,int len)//排序完成后查看结果用{    for(int i=1;i<=len;++i)        cout<<a[i]<<" ";    cout<<endl;}

1.冒泡排序及其改进

冒泡排序是最简单基础的排序,不做过多解释。

void BubbleSort(int *a,int len){    for(int i=1;i<len;++i)        for(int j=len-1;j>=i;--j)            if(a[j]>a[j+1])                Swap(a[j],a[j+1]);    print(a,len);}

下面来看一下其改进算法:

先说明一下优化的内容
当原始数列为:2 1 3 4 5 6 7 8 9
循环进行一次后,变为:1 2 3 4 5 6 7 8 9
已经是有序数列,但程序没有停止,依然在一遍一遍的跑循环。这样会花费很多没有必要的时间。
所以就有了其优化算法:
当某一次循环跑完之后,发现没有进行交换。则可以认为其序列已经有序,没有必要继续进行。跳出循环。

void BetterBubbleSort(int *a,int len){    bool flag;//立一个flag    for(int i=1;i<len;++i){        flag=true;//记得每一次初始化为真        for(int j=len-1;j>=i;--j)        if(a[j]>a[j+1]){            Swap(a[j],a[j+1]);            flag=false;//当交换发生时,标记为假        }        if(flag)//如果flag在循环结束后依然为真,则代表该次循环内没有发生交换,跳出循环            break;    }    print(a,len);}

2.选择排序

每次选择一个未排序列中最小的一个,放到此序列的最前面,这个也非常直观。

void SelectSort(int *a,int len){    int minl;    for(int i=1;i<len;++i){//可以认为前i-1个数都已经有序,且比i之后的数字都小        minl=i;        for(int j=i+1;j<=len;++j)            if(a[minl]>a[j])                minl=j;        if(minl!=i)            Swap(a[i],a[minl]);    }    print(a,len);}

3.插入排序

情况类似于打扑克中发牌时拿牌的情况,每拿到一张牌,和前面拿到的牌进行比较,然后放到适当的位置,这就是插入排序。

void InsertSort(int *a,int len){    for(int i=2;i<=len;++i){//选第i张牌        if(a[i-1]>a[i]){            int j;            a[0]=a[i];            for(j=i-1;a[j]>a[0];--j)//如果比a[i]大,就后退一格,为a[i]腾出位置                a[j+1]=a[j];            a[j+1]=a[0];//正确的位置放入a[i]        }    }    print(a,len);}

总结

O(n^2)的算法都是很简单直观的排序算法,虽然效率不高,但如果能把每一种都自己写出来。对于自己的能力也是一种提升。
而且,只有理解了这些较为简单的排序方法,才能去学习那些更加高效率的排序算法。
基础,往往是最重要的。