美文网首页
选择排序

选择排序

作者: 是一动不动的friend | 来源:发表于2017-11-26 19:37 被阅读2次

基本思想:

在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。

简单选择排序示例

初始值: 3  1  5  7  2  4  9  6
第一趟: 1  3  5  7  2  4  9  6
第二趟: 1  2  5  7  3  4  9  6
第三趟: 1  2  3  7  5  4  9  6
第四趟: 1  2  3  4  5  7  9  6
第五趟: 1  2  3  4  5  7  9  6
第六趟: 1  2  3  4  5  6  9  7
第七趟: 1  2  3  4  5  6  7  9
第八趟: 1  2  3  4  5  6  7  9

操作方法:

第一趟,从n 个记录中找出关键码最小的记录与第一个记录交换;

第二趟,从第二个记录开始的n-1 个记录中再选出关键码最小的记录与第二个记录交换;

......

第 i 趟,则从第 i 个记录开始的 n-i+1 个记录中选出关键码最小的记录与第 i 个记录交换,直到整个序列按关键码有序。

算法的实现:

// 输出数组内容
void print(int array[], int length, int i) {
    printf("i=%d:",i);
    for (int j = 0; j < length; j++) {
        printf(" %d ", array[j]);
    }
    printf("\n");
}

// 获取数组最小值下标
int SelectMinKey(int array[], int length, int i) {
    int k = i;
    for (int j = i + 1; j < length; j ++) {
        if (array[k] > array[j]) {
            k = j;
        }
    }
    return k;
}

// 简单选择排序(Simple Selection Sort)
void SelectSort(int array[], int length) {
    int key, temp;
    for (int i = 0; i < length; i ++) {
        key = SelectMinKey(array, length, i); // 获取最小元素的下标
        if (key != i) { // 最小元素与第i位置元素交换
            temp = array[i];
            array[i] = array[key];
            array[key] = temp;
        }
        print(array, length, i);
    }
}

int main(int argc, const char * argv[]) {
    int arraySelectSort[8] = { 3, 1, 5, 7, 2, 4, 9, 6 };
    SelectSort(arraySelectSort, 8);
    printf("\n");

    return 0;
}

算法的改进(二元选择排序)

简单选择排序,每趟循环只能确定一个元素排序后的定位。我们可以考虑改进为每趟循环确定两个元素(当前趟最大和最小记录)的位置,从而减少排序所需的循环次数。改进后对n个数据进行排序,最多只需进行[n/2]趟循环即可。具体实现如下:

// 二元选择排序
void SelectSort2(int array[], int length) {
    int i, j, min, max;
    for (i = 0; i < length / 2; i ++) { // i 跑 n / 2 趟排序就会排序完成
        min = max = i; // 先将 min 和 max 都指向待排序的第一个元素
        for(j = i; j < length - i; j ++) {
            if (array[j] < array[min]) {
                min = j;
                continue;
            }
            if (array[j] > array[max]) {
                max = j;
            }
        }

        // 将最小值放在第i处,将最大值放在第length-i-1处
        // 注意:这里不能把 array[max]、array[min] 直接和 array[i] 和 array[length-i-1]调换
        int maxtemp = array[max];
        int mintemp = array[min];
        array[max] = array[length-i-1];
        array[min] = array[i];
        array[i] = mintemp;
        array[length-i-1] = maxtemp;

        print(array, 8, i);
    }
}

总结

在简单选择排序过程中,所需移动记录的次数比较少。最好情况下,即待排序记录初始状态就已经是正序排列了,则不需要移动记录。

最坏情况下,即待排序记录初始状态是按第一条记录最大,之后的记录从小到大顺序排列,则需要移动记录的次数最多为3(n-1)。简单选择排序过程中需要进行的比较次数与初始状态下待排序的记录序列的排列情况无关。当i=1时,需进行n-1次比较;当i=2时,需进行n-2次比较;依次类推,共需要进行的比较次数是(n-1)+(n-2)+…+2+1=n(n-1)/2,即进行比较操作的时间复杂度为O(n^2),进行移动操作的时间复杂度为O(n)。

简单选择排序是不稳定排序。

相关文章

  • 算法-选择排序

    算 法:选择排序算法时间复杂度: 选择排序算法概述 选择排序伪代码 选择排序实现 选择排序算法概述 排序算法有许...

  • 常见排序算法

    这里介绍四种排序算法,选择排序、快速排序、归并排序、计数排序 选择排序(使用递归) 选择排序(使用循环) 快速排序...

  • 常用的两种排序-冒泡、选择

    Swift版 冒泡排序 选择排序 OC版 冒泡排序 选择排序

  • 数据结构之排序

    选择排序1.直接选择排序 原理直接选择排序过程直接选择排序过程 实现: DataWrap.java来模拟待排序的数...

  • 记录几个常见的排序算法

    常见的排序有:快速排序、冒泡排序、希尔排序、选择排序、插入排序、归并排序 冒泡排序: 插入排序: 选择排序: 希尔...

  • PHP常用算法

    基于选择的排序算法 常见的基于选择的排序算法有:冒泡排序、插入排序、选择排序、归并排序和快速排序,我们在选在排序算...

  • 排序 -- 选择/插入

    聊聊排序吧 冒泡排序 选择排序 插入排序 快速排序 归并排序 计数排序 桶排序 堆排序 本篇 选择排序与插入排序 ...

  • java快速学习排序---选择排序

    1.java实现选择排序 (1)、图解选择排序 (2)、选择排序的思想 选择排序首先在未排序序列中找到最小(大)元...

  • IOS 常用算法

    一:排序算法 排序方式有插入排序,选择排序和交换排序三种。插入排序有直接插入排序和希尔排序。选择排序有简单选择排序...

  • 给自己备份的排序代码

    交换排序 冒泡排序 快速排序 插入排序 直接插入排序 希尔排序 选择排序 简单选择排序 堆排序

网友评论

      本文标题:选择排序

      本文链接:https://www.haomeiwen.com/subject/uqklbxtx.html