排序算法(简单选择排序)

漫谈简单选择排序

1.从一个简单问题谈起

        给定待排序序列A[ 1.....n ],选择出A中最小的记录(也可以理解为求一个无序数组A中的最小的元素)。下面给出代码如下:

   //选择待排序序列a中的最小记录,其下标为index
    for(index=i=1;i<=n;i++){
        if(a[i]<a[index])
            index=i;
    }</span>

 

2.简单选择排序的过程

        描述:给定待排序序列A[ 1......n ] ,选择出第i小元素,并和A[i]交换,这就是一趟简单选择排序。

        代码:

#include<stdio.h>

//直接插入排序
void  straightInsertSort(int *a,int n)
{
    int i,j;
    int temp;
    //逐个记录插入有序序列
    for(i=2;i<=n;i++){
        temp=a[i];
        //把a[i]插入有序序列
        for(j=i-1;j>=1;j--){
            if(temp<a[j]){
                a[j+1]=a[j];
            }else
                break;
        }
        a[j+1]=temp;
    }
}


void main()
{
    int i;
    int a[7]={0,3,5,8,9,1,2};//不考虑a[0]
    straightInsertSort(a,6);
    for(i=1;i<=6;i++)
        printf("%-4d",a[i]);
    printf("\n");
}

示例:假设给定数组A[1......6]={ 3,5,8,9,1,2 },我们来分析一下A数组进行选择排序的过程

        第一趟:i=1,index=5, a[1] 和 a[5] 进行交换。得到序列:{ 1,5,8,9,3,2 }

        第二趟:i=2,index=6, a[2] 和 a[6] 进行交换。得到序列:{ 1,2,8,9,3,5 }

        第三趟:i=3,index=5, a[3] 和 a[5] 进行交换。得到序列:{ 1,2,3,9,8,5 }

        第四趟:i=4,index=6, a[3] 和 a[5] 进行交换。得到序列:{ 1,2,3,5,8,9 }

        第五趟:i=5,index=5, 不用交换。得到序列:{ 1,2,3,5,8,9 }

       (6-1)趟选择结束,得到有序序列:{ 1,2,3,5,8,9 }

 3.性能分析

容易看出,简单选择排序所需进行记录移动的操作次数较少,这一点上优于冒泡排序,最佳情况下(待排序序列有序)记录移动次数为0,最坏情况下(待排序序列逆序)记录移动次数n-1。外层循环进行了n-1趟选择,第i趟选择要进行n-i次比较。每一趟的时间:n-i次的比较时间+移动记录的时间(为一常数0或1,可以忽略)。总共进行了n-1趟。忽略移动记录的时间,所以总时间为(n-1)*(n-i)=n^2-(i+1)*n+i。时间复杂度为O(n^2)。不管是最坏还是最佳情况下,比较次数都是一样的,所以简单选择排序平均时间、最坏情况、最佳情况 时间复杂度都为O(n^2)。同时简单选择排序是一种稳定的原地排序算法。当然稳定性还是要看具体的代码,在此就不做深究。   

4.简单选择排序引发的思考    

第一趟排序后:{ 1,5,8,9,3,2 } ,此时A[ 1 ]已经有序,我们可以把待排序序列缩减到A[ 2......6 ]

第二趟排序后:{ 1,2,8,9,3,5 },此时A[ 1...2 ]已经有序,我们可以把待排序序列缩减到A[ 3......6 ]

第三趟排序后:{ 1,2,3,9,8,5 },此时A[ 1...3 ]已经有序,我们可以把待排序序列缩减到A[ 4......6 ]

第四趟排序后:{ 1,2,3,5,8,9 },此时A[ 1...4 ]已经有序,我们可以把待排序序列缩减到A[ 5......6 ]

第五趟排序后:{ 1,2,3,5,8,9 },此时A[ 1...5 ]已经有序,我们可以把待排序序列缩减到A[ 6......6 ]

也就是说第i趟后,A[ 1...i ]已经有序,待排序序列缩减为A[ (i+1)...n ]。这是一个待排序序列中记录不断减少的递归过程。也许很多读者已经发现,我们每次都是从待排序序列中选择最小的那个记录然后跟待排序序列的首元素进行交换。于是可以用一个递归函数来进行简单选择排序,代码如下:

//递归函数进行简单选择排序
void simpleSelectionSort2(int *a,int n)
{
    int index,i;
    if(n==1)
        return;
    //1.选择待排序序列a中的最小记录,其下标为index
    for(index=i=1;i<=n;i++){
        if(a[i]<a[index])
            index=i;
    }
    //2.最小记录与待排序序列首元素进行交换
    if(index!=1){
        a[1]=a[1]+a[index];
        a[index]=a[1]-a[index];
        a[1]=a[1]-a[index];
    }
    //3.待排序序列元素个数减少,递归对剩下的无序序列排序
    simpleSelectionSort2(a+1,n-1);
}</span>

 

 

转载于:https://www.cnblogs.com/lovehyy/articles/3891006.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值