选择排序

Posted mango-tree

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了选择排序相关的知识,希望对你有一定的参考价值。

选择排序

选择排序的思想就是从待排数组中将最小的一个元素筛选出来并移动到数组最前端,然后将待排数组的范围缩小(即将已排序的第一个元素排除在外),循环对待排数组进行相同排序处理,直到所有元素都已经排好序
假定初始数组为{3,5,4,2,1}
技术图片
第一次排序后得到{1,5,4,2,3}
技术图片
第二次排序后得到{1,2,4,5,3}
技术图片
第三次排序后得到{1,2,3,5,4}
技术图片
第四次排序后得到{1,2,3,4,5}
技术图片
第五次排序后得到{1,2,3,4,5}
技术图片
对应的算法代码为:

static void Selection(int[] arr) {
    for (int i = 0; i < arr.length - 1; i++) {
        int index = i;
        for (int j = index + 1; j < arr.length; j++) {
            index = arr[j] < arr[index] ? j : index;
        }
        Utils.swap(arr, i, index);//交换arr数组中下标为i和index的两个索引的值
    }
}

优化

上述选择排序算法一次遍历只是找出待排数组中最小的一个值,然后插入到数组头位置,优化的思路就是在每次遍历的过程中不止找出待排数组中的最小值放到头位置,同时也找出最大值放到尾位置
对应的算法代码为:

static void SelectionEnhanced1(int[] arr) {
    for (int i = 0; i < arr.length / 2; i++) {
        int minPos = i, min = minPos, maxPos = arr.length - i - 1, max = maxPos;
        for (int j = min; j <= max; j++) {
            minPos = arr[j] < arr[minPos] ? j : minPos;
            maxPos = arr[j] > arr[maxPos] ? j : maxPos;
        }
        Utils.swap(arr, min, minPos);
        Utils.swap(arr, max, maxPos);
    }
}

再次优化???

经过上述优化后的代码已经可以在一次遍历时将待排数组中的最大值和最小值放置到指定位置,那么在此基础上还可以进行优化吗?其实也是可以的,对代码每次循环所增长的步长进行变化可以减少进入循环体的次数,从而达到优化的目的,以下代码相比较于基础方式,循环体代码的执行次数最高可以降低到原有的四分之一
对应的算法代码为:

static void SelectionEnhanced2(int[] arr) {
    for (int i = 0; i < arr.length / 2; i++) {
        int minPos = i, min = minPos, maxPos = arr.length - i - 1, max = maxPos;
        for (int j = min; j <= max; j += 2) {
            minPos = arr[j] < arr[minPos] ? j : minPos;
            maxPos = arr[j] > arr[maxPos] ? j : maxPos;
            if (j + 1 <= max) {
                minPos = arr[j + 1] < arr[minPos] ? j + 1 : minPos;
                maxPos = arr[j + 1] > arr[maxPos] ? j + 1 : maxPos;
            }
        }
        //该代码还有Bug,即在交换的时候需要考虑一些特殊情况的处理,感兴趣的可以自行发掘改正
        Utils.swap(arr, min, minPos);
        Utils.swap(arr, max, maxPos);
    }
}

通过对数器的方式进行排序结果的验证

//测试代码
public static void main(String[] args) {
    int size = 15;
    //自定义方法:用于获取指定个数和数值范围的数组的方法
    int[] arr1 = Utils.generateRandomArray(size, 100);
    int[] arr2 = new int[size];
    System.arraycopy(arr1, 0, arr2, 0, arr1.length);
    int[] arr3 = new int[size];
    System.arraycopy(arr1, 0, arr3, 0, arr1.length);
    int[] arr4 = new int[size];
    System.arraycopy(arr1, 0, arr4, 0, arr1.length);
    System.out.println("原数组:					" + Arrays.toString(arr1));
    Arrays.sort(arr1);
    System.out.println("系统方法排序后:			" + Arrays.toString(arr1));
    Selection(arr2);
    System.out.println("基础选择排序排序后:		" + Arrays.toString(arr2));
    SelectionEnhanced1(arr3);
    System.out.println("优化版选择排序排序后:	" + Arrays.toString(arr3));
    SelectionEnhanced1(arr4);
    System.out.println("再次优化版选择排序排序后:	" + Arrays.toString(arr4));
}
原数组:			[47, 48, 50, 75, 30, 84, 16, 49, 2, 31, 22, 90, 21, 33, 14]
系统方法排序后:		[2, 14, 16, 21, 22, 30, 31, 33, 47, 48, 49, 50, 75, 84, 90]
基础选择排序排序后:		[2, 14, 16, 21, 22, 30, 31, 33, 47, 48, 49, 50, 75, 84, 90]
优化版选择排序排序后:	        [2, 14, 16, 21, 22, 30, 31, 33, 47, 48, 49, 50, 75, 84, 90]
再次优化版选择排序排序后:	[2, 14, 16, 21, 22, 30, 31, 33, 47, 48, 49, 50, 75, 84, 90]

如果对你有帮助,点个赞,或者打个赏吧,嘿嘿
整理不易,请尊重博主的劳动成果

















以上是关于选择排序的主要内容,如果未能解决你的问题,请参考以下文章

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

VSCode自定义代码片段——CSS选择器

VSCode自定义代码片段6——CSS选择器

在第6731次释放指针后双重免费或损坏

微信小程序代码片段

pycharm添加Odoo代码片段