选择排序

选择排序

代码#

import java.util.Arrays;

public class SelectionSort {
    public static void main(String[] args) {
        int[] numbers = { 3, 1, 4, 2, 6, 5 };
        System.out.println("排序前的数组为:" + Arrays.toString(numbers));
        // 记录每一轮比较的最小值下标
        int minIndex = 0;
        // 外层循环控制比较轮数
        for (int i = 0; i < numbers.length - 1; i++) {
            minIndex = i;
            // 内层循环控制每轮中的比较
            for (int j = i + 1; j < numbers.length; j++) {
                // 如果被比较的数小于当前下标的数,则改变下标
                if (numbers[minIndex] > numbers[j]) {
                    minIndex = j;
                }
                //  当下标发生改变则边换一次数值
                if (minIndex != i) {
                    numbers[minIndex] += numbers[i];
                    numbers[i] = numbers[minIndex] - numbers[i];
                    numbers[minIndex] -= numbers[i];
                }
            }
        }
        System.out.println("排序后的数组为:" + Arrays.toString(numbers));
    }
}

输出效果为:

排序前的数组为:[3, 1, 4, 2, 6, 5]

排序后的数组为:[1, 2, 3, 4, 5, 6]

释义#

选择排序,每轮排序从待排序元素中选出极值,存放到序列起始位置,接着从剩余元素选出极值,放在序列已排序元素的后面,直至元素排序完毕。

以[3, 1, 4, 2, 6, 5]为例将选择排序逐步理顺。
第一轮,共比较五次:
[3, 1, 4, 2, 6, 5] minIndex = 0初始
[3, 1, 4, 2, 6, 5] minIndex = 13跟1比,1小,标记改变
[3, 1, 4, 2, 6, 5] minIndex = 11跟4比,1小,标记不变
[3, 1, 4, 2, 6, 5] minIndex = 13跟2比,1小,标记不变
[3, 1, 4, 2, 6, 5] minIndex = 13跟6比,1小,标记不变
[3, 1, 4, 2, 6, 5] minIndex = 13跟5比,1小,标记不变
[1, 3, 4, 2, 6, 5]第一轮比较结束选出最小元素跟下标元素交换位置

第二轮,共比较4次,最小元素已选出,比较中隐藏。
[3, 4, 2, 6, 5] minIndex = 1初始
[3, 4, 2, 6, 5] minIndex = 13跟4比,3小,标记不变
[3, 4, 2, 6, 5] minIndex = 33跟2比,2小,标记改变
[3, 4, 2, 6, 5] minIndex = 32跟6比,2小,标记不变
[3, 4, 2, 6, 5] minIndex = 32跟5比,2小,标记不变
[2, 4, 3, 6, 5]第二轮比较结束选出最小元素跟下标元素交换位置

第三轮,共比较3次:
[4, 3, 6, 5] minIndex = 2初始
[4, 3, 6, 5] minIndex = 34跟3比,3小,标记改变
[4, 3, 6, 5] minIndex = 33跟6比,3小,标记不变
[4, 3, 6, 5] minIndex = 33跟5比,3小,标记不变
[3, 4, 6, 5]第三轮比较结束选出最小元素跟下标元素交换位置

第四轮,共比较2次:
[4, 6, 5] minIndex = 3初始
[4, 6, 5] minIndex = 34跟6比,4小,标记不变
[4, 6, 5] minIndex = 34跟5比,4小,标记不变
[4, 6, 5]第四轮比较结束,下标没发生变化,不交换位置

第五轮,共比较1次:
[6, 5] minIndex = 4初始
[6, 5] minIndex = 56跟5比,5小,标记改变
[5, 6]第五轮比较结束元素交换位置

经过五轮的比较,排序完成得到序列[1, 2, 3, 4, 5, 6]。

外层循环控制比较轮数,假设有N个元素待比较,循环的次数应该是N-1。
条件为int i = 0; i < numbers.length - 1; i++
内层循环控制每轮比较的次数。每轮比较的初始下标与后面的元素比较比较到最后一个元素。
条件为int j = i + 1; j < numbers.length; j++

总结#

选择排序的比较次数在0n-1之间,比较次数为n(n-1)/2次,赋值操作介于03(n-1)次之间。交换次数比冒泡排序较少,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。

平均时间复杂度:O(n²)
最坏时间复杂度:O(n²)
最好时间复杂度:O(n)
空间复杂度:O(1)

选择排序是一种不稳定的排序算法,两个相同数值的顺序可能会发生变化。

原地操作几乎是选择排序的唯一优点,当空间复杂度要求较高时,可以考虑选择排序;实际适用的场合非常罕见。

posted @   isxh  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
主题色彩