码迷,mamicode.com
首页 > 编程语言 > 详细

选择排序

时间:2020-06-30 00:37:46      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:one   兴趣   load   思想   select   之一   数值   index   图片   

选择排序

选择排序的思想就是从待排数组中将最小的一个元素筛选出来并移动到数组最前端,然后将待排数组的范围缩小(即将已排序的第一个元素排除在外),循环对待排数组进行相同排序处理,直到所有元素都已经排好序
假定初始数组为{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("原数组:\t\t\t\t\t" + Arrays.toString(arr1));
    Arrays.sort(arr1);
    System.out.println("系统方法排序后:\t\t\t" + Arrays.toString(arr1));
    Selection(arr2);
    System.out.println("基础选择排序排序后:\t\t" + Arrays.toString(arr2));
    SelectionEnhanced1(arr3);
    System.out.println("优化版选择排序排序后:\t" + Arrays.toString(arr3));
    SelectionEnhanced1(arr4);
    System.out.println("再次优化版选择排序排序后:\t" + 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]

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

选择排序

标签:one   兴趣   load   思想   select   之一   数值   index   图片   

原文地址:https://www.cnblogs.com/Mango-Tree/p/13211130.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!