排序算法——选择排序(含递归实现和改进)

选择排序

思想:

​        如果有N个元素需要排序,那么首先从N个元素中找到最小的那个元素与第0位置上的元素交换,然后再从剩下的N-1个元素中找到最小的元素与第1位置上的元素交换,之后再从剩下的N-2个元素中找到最小的元素与第2位置上的元素交换,.......直到所有元素都排序好。

​        优化:选择排序平均时间复杂度O(N^2),还可以进行优化,可以在一次[数组遍历](https://so.csdn.net/so/search?q=数组遍历&spm=1001.2101.3001.7020)中同时找到最大值和最小值,这样就减少了数组的循环次数,效率提高。

代码

示例(未优化):


// 未优化
// 采用两层循环实现的方法。
// 参数arr是待排序数组的首地址,len是数组元素的个数。
void selectsort1(int arr[], int len)
{
    for(int ii=0;ii<len-1;ii++)
    {
        int posmin = ii;    // 每趟循环选出的最小值的位置(数组的下标)。
        for(int jj=ii+1;jj<len;jj++)  // 每趟只需要比较ii+1......len-1之间的元素,ii之前的元素是已经排序好的。
        {
            // 找出值更小的元素,记下它的位置。
            if(arr[posmin]>arr[jj])   posmin = jj;
        }
        // 如果本趟循环的最小的元素不是起始位置的元素,则交换它们的位置。
        if (posmin != ii) swap(arr[ii],arr[posmin]);
    }
}

// 采用递归实现的方法。
// 参数arr是待排序数组的首地址,len是数组元素的个数。
void selectsort2(int arr[], int len)
{
    if(len==0) return;

    int posmin = 0;     // 每趟循环选出的最小值的位置(数组的下标)。
    for(int ii=0;ii<len;ii++)
    {
        // 找出值更小的元素,记下它的位置。
        if(arr[posmin]>arr[ii]) posmin = ii;
    }
    // 如果本趟循环的最小的元素不是起始位置的元素,则交换它们的位置。
    if (posmin != 0) swap(arr[0],arr[posmin]);
    
    selectsort2(arr+1,--len);   // 递归调用自身
}

示例(优化后):


// 未优化
// 采用两层循环实现的方法。
// 参数arr是待排序数组的首地址,len是数组元素的个数。
void selectsort1(int arr[], int len)
{
    for(int ii=0;ii<len-1;ii++)
    {
        int posmin = ii;    // 每趟循环选出的最小值的位置(数组的下标)。
        for(int jj=ii+1;jj<len;jj++)  // 每趟只需要比较ii+1......len-1之间的元素,ii之前的元素是已经排序好的。
        {
            // 找出值更小的元素,记下它的位置。
            if(arr[posmin]>arr[jj])   posmin = jj;
        }
        // 如果本趟循环的最小的元素不是起始位置的元素,则交换它们的位置。
        if (posmin != ii) swap(arr[ii],arr[posmin]);
    }
}

// 采用递归实现的方法。
// 参数arr是待排序数组的首地址,len是数组元素的个数。
void selectsort2(int arr[], int len)
{
    if(len==0) return;

    int posmin = 0;     // 每趟循环选出的最小值的位置(数组的下标)。
    for(int ii=0;ii<len;ii++)
    {
        // 找出值更小的元素,记下它的位置。
        if(arr[posmin]>arr[ii]) posmin = ii;
    }
    // 如果本趟循环的最小的元素不是起始位置的元素,则交换它们的位置。
    if (posmin != 0) swap(arr[0],arr[posmin]);
    
    selectsort2(arr+1,--len);   // 递归调用自身
}

算法分析

时间复杂度:

  1. 最好:O(n^2)
  2. 最坏:O(n^2)
  3. 平均:O(n^2)

空间复杂度:O(1)

稳定性:稳定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值