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

一、介绍

1、冒泡排序的基本思想就是不断地比较、交换,通过交换完成最终的排序;而相比冒泡排序来说,选择排序法的基本思想是在排序时找到合适的关键字再做交换,且只移动一次就完成相应关键字的排序定位,也就是说每一趟在n - i + 1(i = 1, 2......, n - 1)个记录中选取关键字最小的记录作为有序序列的第i个记录。

二、简单选择排序算法

1、简单选择排序法(Simple Selection Sort)就是每次通过n - i次关键字间的比较,从n - i + 1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录进行交换。

2、简单选择排序算法实现

#include <stdio.h>

// 定义待排序记录类型
typedef int RecordType;

/**
 * 将待排序记录数组的下标i和下标j的两个记录进行交换
 */
void Swap(RecordType *rs, int i, int j)
{
    RecordType tmp = *(rs + i);
    *(rs + i) = *(rs + j);
    *(rs + j) = tmp;
}
/**
 * 打印待排序记录数组
 */
void PrintRs(RecordType rs[])
{
    int i, count = rs[0];

    for (i = 1; i <= count; i++)
    {
        printf("%d ", rs[i]);
    }
    printf("\n");
}

/**
 * 对记录列表进行简单选择排序
 */
void SimpleSelectionSort(RecordType *rs)
{
    int i, j, count = rs[0];
    int min;    // 用于保存每趟比较中最小的记录的下标
    for (i = 1; i < count; i++)
    {
        min = i;    // 首先将min初始化为这一趟比较的第一个记录的下标
        for (j = i + 1; j <= count; j++)
        {
            if (*(rs + min) > *(rs + j))
            {
                min = j;   // 如果当次比较发现下标j的记录更小,则使得min指向该记录的下标
            }
        }

        // 该趟比较完毕,如果min不再指向初始记录下标,说明找到了更小的记录,则进行交换
        if (min != i)
        {
            Swap(rs, i, min);
        }
    }
}

int main()
{
    RecordType rs[] = {5, 1, 5, 3, 2, 4};
    printf("排序前记录列表排序为:\t\t");
    PrintRs(rs);
    SimpleSelectionSort(rs);
    printf("从小到大排序后,记录列表排序为:");
    PrintRs(rs);
    return 0;
}
3、时间复杂度

从以上简单选择排序的实现来看,最大的特点就是减少了每一趟比较过程中的记录交换次数,所以能节约不少时间。对于时间复杂度来说,无论是最好还是最坏情况,其比较次数都是一样的,对于第i趟排序需要进行n - i次关键字的比较,所以共需要比较n(n - 1)/2次;但是对于交换次数来说,最好的情况就是记录本身有序,无需交换;最坏情况就是记录是倒序排列的,交换次数需要n - 1次,基于最终的排序时间是比较和交换的次数总和,所以总的时间复杂度为O(n^2)。


参考书籍:《大话数据结构》


你可能感兴趣的:(数据结构,算法,排序,简单选择排序)