【数算-08】选择排序

1、选择排序算法思路

在这里插入图片描述选择排序(select sorting)也是一种简单的排序方法。它的基本思想是:第一次从arr[0]arr[n-1]中选取最小值,与arr[0]交换,第二次从arr[1]arr[n-1]中选取最小值,与arr[1]交换,第三次从arr[2]arr[n-1]中选取最小值,与arr[2]交换,…,第i次从arr[i-1]arr[n-1]中选取最小值,与arr[i-1]交换,…, 第n-1次从arr[n-2]~arr[n-1]中选取最小值,与arr[n-2]交换,总共通过n-1次,得到一个按排序码从小到大排列的有序序列。

2、选择排序算法图解

在这里插入图片描述
在这里插入图片描述

3、选择排序算法实现(已优化)

优化思路:
在不断确定最小数时,如果最小数所对应的序号没有发生改变(也就是说该数的最终位置就在当前位置上),此时就不需要在对最小数与当前位置数进行交换了

import org.junit.Test;

import java.util.Arrays;

/**
 * @author zhihua.li
 * @date 2021/2/2 - 12:13
 **/
public class SelectSorting {
    /*
        选择排序思想:逐步确定最小数,并放在第0,1,2...个位置上
            第一趟,确定数组中的最小数位于第1个位置,要比较n-1次
            第二趟,保证数组中第2小数位于第2个位置,比较n-2次
            第三趟,保证数组中第3小数位于第3个位置,循环n-3次
            ...
           直至除最后一个位置的数外,其他n-1个数都确定了其对应的位置,返回排序后的序列
    */

    /*
        选择排序推导过程:

            第一轮:
        int minIndex = 0;
        int min = arr[minIndex];
        for (int i = 0+1; i < arr.length; i++) {
            if (arr[i] < min) {     //若arr[i]<min,说明假定的最小值,并不是真的最小值
                minIndex = i;       //重置minIndex
                min = arr[minIndex];    //重置min值
            }
        }
        //将最小值放在arr[0]上
        arr[minIndex] = arr[0];
        arr[0] = min;
        System.out.println("第一趟排序获得到的数组序列为:"+ Arrays.toString(arr));

            第二轮:
        minIndex = 1;
        min = arr[minIndex];
        for (int i = 1+1; i < arr.length; i++) {
            if (arr[i] < min) {     //若arr[i]<min,说明假定的最小值,并不是真的最小值
                minIndex = i;       //重置minIndex
                min = arr[minIndex];    //重置min值
            }
        }
        将最小值放在arr[1]上
        arr[minIndex] = arr[1];
        arr[1] = min;
        System.out.println("第二趟排序获得到的数组序列为:"+ Arrays.toString(arr));


            第三轮:
        minIndex = 2;
        min = arr[minIndex];
        for (int i = 1+1; i < arr.length; i++) {
            if (arr[i] < min) {     //若arr[i]<min,说明假定的最小值,并不是真的最小值
                minIndex = i;       //重置minIndex
                min = arr[minIndex];    //重置min值
            }
        }
        //将最小值放在arr[2]上
        arr[minIndex] = arr[2];
        arr[2] = min;
        System.out.println("第二趟排序获得到的数组序列为:"+ Arrays.toString(arr));

    */


    /**
     * @param arr
     * @Method selectSort
     * @Author zhihua.Li
     * @Version 1.0
     * @Description 正式的选择排序算法:
     * 外层循环控制:第0,1,2,3...个位置上的元素依次是多少
     * 内层循环控制:将当前外层循环上的arr[i]开始到最后的最小元素,分别记录其下标和值
     * @Return void
     * @Exception
     * @Date 2021/2/2 12:16
     */
    private void selectSort(int arr[]) {

        for (int i = 0; i < arr.length - 1; i++) {
//            假设当前位置是最小值,即正好处于有序序列中的对应位置
            int minIndex = i;
            int min = arr[i];
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < min) {
                    minIndex = j;
                    min = arr[minIndex];
                }
            }
//            如果当前位置上元素发生过变化,就交换当前位置与记录下标位置上的元素值
            if (minIndex != i) {
                arr[minIndex] = arr[i];
                arr[i] = min;
            }
            System.out.println("第" + (i + 1) + "趟排序获得到的数组序列为:" + Arrays.toString(arr));
        }
    }

4、选择排序算法分析

1、算法代码测试
@Test
    public void test() {
        int[] arr = {34, 101, 119, 1};
        selectSort(arr);
   }
   

测试结果:
在这里插入图片描述
通过代码可以发现选择排序算法的时间复杂度为O(n^2)

2、当面对大量待排序数据时,测试选择排序的耗时
@Test
    public void test() {
        int[] arr = new int[80000];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random() * 8000000);
        }
        System.out.println("排序前的序列为:" + Arrays.toString(arr));
        long l1 = System.currentTimeMillis();
        selectSort(arr);
        long l2 = System.currentTimeMillis();
        System.out.println("排序后的序列为:" + Arrays.toString(arr));
        System.out.println("选择排序所用时间为:" + (l2 - l1) + "ms");
   }

测试结果:
在这里插入图片描述
结果显示:选择排序时间效率要明显高于冒泡排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pascalzhli

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值