排序算法的总结(插入排序、冒泡排序、选择排序)

三种简单排序算法的总结(插入排序、冒泡排序、选择排序)


1.插入排序:插入排序(Insert Sort)基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为Θ(n2)。是稳定的排序方法。插入排序的基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。(也就是在一组数据中,从前至后,把小(或大)的往前插,其实也是交换顺序)

简单插入排序在最好情况下,需要比较n-1次,无需交换元素,时间复杂度为Θ(n);在最坏情况下,时间复杂度为Θ(n2)

代码如下:

void inssort(int a[],int length) //从前至后,把小的往前插,其实也是交换顺序
{
    int temp =0;
    for(int i=1;i<length; i++)
    {
        int j=i;
        while(j>0&&a[j]<a[j-1]){
            temp=a[j-1];
            a[j-1]=a[j];
            a[j]=temp;
            j--;
            }
    }

}

2.冒泡排序:冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的数列,一次比较相邻两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小(或大)的元素会经由交换慢慢到数列的顶端。

优化:在冒泡排序的过程中,如果某一趟执行完毕,没有做任何一次交换操作,即一次交换都没有做,这就说明剩下的序列已经是有序的,排序操作也就可以完成了。(可以设置一个flag来标记是否进行过交换)

代码如下:

void bubsort(int a[],int length)//从后至前,每一次把最小的泡出去
{
    int temp=0;
    for(int i=0;i<length-1;i++)
        {
            for(int j=length-1;j>i;j--)  //j>i执行for是因为已经表示前有i排好序了
            {
                if(a[j]<a[j-1])
                {
                    temp=a[j-1];
                    a[j-1]=a[j];
                    a[j]=temp;
                }
            }
        }
}

3.选择排序:选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。选择排序是不稳定的排序方法。在算法实现时,每一趟确定最小元素的时候会通过不断地比较交换来使得首位置为当前最小,交换是个比较耗时的操作。(类似于冒泡排序)

优化:其实我们很容易发现,在还未完全确定当前最小元素之前,这些交换都是无意义的。我们可以通过设置一个变量lowindex,每一次比较仅存储较小元素的数组下标,当轮循环结束之后,那这个变量存储的就是当前最小元素的下标,此时再执行交换操作即可。

  简单选择排序通过上面优化之后,无论数组原始排列如何,比较次数是不变的;对于交换操作,在最好情况下也就是数组完全有序的时候,无需任何交换移动,在最差情况下,也就是数组倒序的时候,交换次数为n-1次。综合下来,时间复杂度为Θ(n2)。

代码如下:

void selsort(int a[],int length)
{
    int temp =0;
    for(int i=0; i<length-1;i++)
    {
        int lowindex =i;
        for(int j=length-1;j>i;j--)
        {
            if(a[j]<a[lowindex])  //比起冒泡排序只需多判断与lowindex对应的值找到最小做交换,交换的次数要少很多
            {
                lowindex=j;
            }
        }
        temp = a[i];
        a[i]=a[lowindex];
        a[lowindex]=temp;
    }
}

测试函数:

int main()
{
    int a[5]={5,3,8,2,6};
    inssort(a,5);
 //   bubsort(a,5);
 //   selsort(a,5);

    for(int i=0;i<5;i++)
    cout<<a[i]<<" ";
}

4、下面列出了插入排序、冒泡排序、选择排序分别在最佳、平均和最差情况下的比较次数和交换次数。三种方法在平均及最差情况下的时间代价皆为Θ(n2)


 

 

插入排序

冒泡排序

选择排序

进行比较时

最佳情况

Θ(n)

Θ(n2)

Θ(n2)

平均情况

Θ(n2)

Θ(n2)

Θ(n2)

最差情况

Θ(n2)

Θ(n2)

Θ(n2)

 

进行交换时

最佳情况

0

0

Θ(n)

平均情况

Θ(n2)

Θ(n2)

Θ(n)

最差情况

Θ(n2)

Θ(n2)

Θ(n)


猜你喜欢

转载自blog.csdn.net/lanyandong/article/details/78671536