选择排序—直接选择排序

直接选择排序也成为简单选择排序。

排序思想

对于一个待排序数列,每次从无序区选择一个最小的元素,放入有序区(初始时有序区为空),直到无序区元素只有一个(即整个数列的最大值)。

具体操作:第i趟排序开始,数列分为有序区a[0,i-1]和无序区a[i,n-1]。从无序区中选择最小元素a[k],将a[k]放在无序区的最左边的位置:a[k]<->a[i]互换位置。直到无序区元素为一个。

代码实现

#include <iostream>

using namespace std;

void selectSort(int a[],int n){
    int i,j,k,tmp;
    for(i=0;i<n-1;i++){//需要进行n-1趟选择
        k=i;//k用来存放每一趟中最小的值的下标
        for(j=i+1;j<n;j++){//每一趟中对应无序区中选择(这里k=i也算在其中,即无序区:[i,(n-1)])
            if(a[j]<a[k])
                k=j;
        }
        
        //如果最小的值不是i位置,就替换
        if(k!=i){
            tmp=a[k];
            a[k]=a[i];
            a[i]=tmp;
        }
    }
}

int main()
{
    int a[]={9,8,7,6,5,4,3,2,1,0};
    selectSort(a,10);
    for(int i=0;i<10;i++){
        cout << a[i] << endl;
    }

    return 0;
}

算法分析

无论初始数据排列如何,第i趟选出最小元素,内层for循环需要进行n-(i+1)=n-i-1次比较

总的比较次数

C(n)=\sum_{i=0}^{n-2}(n-i-1)=\frac{n(n-1)}{2}=O(n^2)

对于元素的移动次数,如果初始数列为正序,则移动次数为0;如果初始为反序,每趟均需执行交换操作,总共需要移动3(n-1)。

关键词比较次数是确定的为\frac{n(n-1)}{2}

所以平均时间复杂度为O(n^2)

在直接排序算法中只用到i,j,k,tmp4个变量,与问题规模n 无关,所以空间复杂度为O(1)

直接排序算法是一个不稳定的排序方法,例如,{5,3,2,5,4,1,8,7},第一趟选择最小元素1,并交换{1,3,2,5,4,5,8,7},两个5的相对位置发生了改变。

猜你喜欢

转载自blog.csdn.net/SICAUliuy/article/details/88924819