数据结构与算法(12):选择排序(含相关的实例)

一:选择排序
基本介绍
  选择式排序也属于内部排序法,是从待排序的数据中,按照指定的规则选出某一元素,再依规定交换位置后达到排序的目的

选择排序思想:

选择排序(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次,得到一个按排序码从小到大排列的有序序列。

以上说总结一句话:就是说每次数组中挑选出最小的数,放在最前头,再从剩下的数组中挑选出最小的放在第二位,依次类推.

原始的数组:101,34,119,1
第一轮排序:1 34 119 101
第二轮排序:1,34,119,101
第三轮排序:1,34,101,119
说明:

  1. 选择排序一共有(数组大小-1)轮排序
  2. 每一轮排序又是一个循环,循环的规则(代码)
    2.1 先假定当前的这个数是最小的.
    2.2 然后和后面的每个数进行比较,如果发现有比当前数更小的数.就重新确定最小数.并得到下标
    2.3 当遍历到数组的最后是,就得到本轮最小的数和下标
    2.4 交换

选择排序的应用实例:
有一群牛,颜值分别是101,34,119,1请使用选择排序从低到高进行排序[101,34,119,1]

推导代码:

package com.qiu.sort;

import java.util.Arrays;

public class SelectSort {
    public static void main(String[] args) {
        int[] arr = {101,34,119,1};
        selectSort(arr);
    }

    //选择排序
    public static void selectSort(int[] arr){
        //使用逐步推导的顺序
        //第一轮原始的数组:101,34,119,1
        //第一轮排序:1 34 119 101
        //算法:先简单,再复杂
        int minIndex = 0;
        int min =arr[0];//假定这个数为零
        for (int j = 0+1; j <arr.length ; j++) {
            //这里的0+1,的意思就是说我们假定了这个数组的第一个数就是最小数,然后循环从第二个数开始
            if (min>arr[j]){
                //说明我们假定的最小值就不是最小的
                min = arr[j];//重置最小值
                minIndex = j;//重置最小值的索引
            }
        }
        //将这个最小值放在arr[0]这个位置.即交换
        //从上面循环代码来讲:扫描到的最小值的minIndex为3,这个minIndex为3
        if (minIndex !=0){
            arr[minIndex] = arr[0];//这里的arr[0]为101,这里就是说把101,放到之前扫描到那个最小的位置
            arr[0] = min;//接着讲拿到的这个最小值,放在数组下边为0的这个位置
        }



        System.out.println("第一轮后");
        System.out.println(Arrays.toString(arr));

        //第一轮排序:1 34 119 101
        //算法:先简单,再复杂
        minIndex = 1;
        min =arr[1];//假定这个数为零
        for (int j = 1+1; j <arr.length ; j++) {
            //这里的0+1,的意思就是说我们假定了这个数组的第一个数就是最小数,然后循环从第二个数开始
            if (min>arr[j]){
                //说明我们假定的最小值就不是最小的
                min = arr[j];//重置最小值
                minIndex = j;//重置最小值的索引
            }
        }
        //将这个最小值放在arr[0]这个位置.即交换
        //从上面循环代码来讲:扫描到的最小值的minIndex为3,这个minIndex为3
        if (minIndex !=0){
            arr[minIndex] = arr[1];//这里的arr[0]为101,这里就是说把101,放到之前扫描到那个最小的位置
            arr[1] = min;//接着讲拿到的这个最小值,放在数组下边为0的这个位置
        }


        System.out.println("第二轮后");
        System.out.println(Arrays.toString(arr));
        //第一轮排序:1 34 119 101
        //算法:先简单,再复杂
        minIndex = 2;
        min =arr[2];//假定这个数为零
        for (int j = 2+1; j <arr.length ; j++) {
            //这里的0+1,的意思就是说我们假定了这个数组的第一个数就是最小数,然后循环从第二个数开始
            if (min>arr[j]){
                //说明我们假定的最小值就不是最小的
                min = arr[j];//重置最小值
                minIndex = j;//重置最小值的索引
            }
        }
        //将这个最小值放在arr[0]这个位置.即交换
        //从上面循环代码来讲:扫描到的最小值的minIndex为3,这个minIndex为3
        if (minIndex !=0){
            arr[minIndex] = arr[2];//这里的arr[0]为101,这里就是说把101,放到之前扫描到那个最小的位置
            arr[2] = min;//接着讲拿到的这个最小值,放在数组下边为0的这个位置
        }


        System.out.println("第三轮后");
        System.out.println(Arrays.toString(arr));
    }



}

代码调优:

package com.qiu.sort;

import java.util.Arrays;

public class SelectSort {
    public static void main(String[] args) {
        int[] arr = {101,34,119,1};
        selectSort(arr);
    }

    //选择排序
    public static void selectSort(int[] arr){
        //使用逐步推导的顺序
        //第一轮原始的数组:101,34,119,1
        //第一轮排序:1 34 119 101
        //算法:先简单,再复杂
        //在推导的过程中,我们发现了规律,因此可以使用for循环来解决问题
        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++) {
                //这里的0+1,的意思就是说我们假定了这个数组的第一个数就是最小数,然后循环从第二个数开始
                if (min>arr[j]){
                    //说明我们假定的最小值就不是最小的
                    min = arr[j];//重置最小值
                    minIndex = j;//重置最小值的索引
                }
            }
            //将这个最小值放在arr[0]这个位置.即交换
            //从上面循环代码来讲:扫描到的最小值的minIndex为3,这个minIndex为3
            if (minIndex !=i){
                arr[minIndex] = arr[i];//这里的arr[0]为101,这里就是说把101,放到之前扫描到那个最小的位置
                arr[i] = min;//接着讲拿到的这个最小值,放在数组下边为0的这个位置
            }



            System.out.println("第"+(i+1)+"轮后:");
            System.out.println(Arrays.toString(arr));
        }
        
        
    }



}

代码运行显示:
在这里插入图片描述同样的两个for循环.所以这里的时间负复杂度为O(n^2)

选择排序的速度测试:
同样的我们添加如下代码:

  //测试一下冒泡排序的速度,给8w随机数组
        int[] arr1 = new int[80000];
        for (int i = 0; i < 80000; i++) {
            arr1[i] =(int)(Math.random()*80000000);

        }
        //测试排序时间
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = format.format(date);
        System.out.println("排序前的时间:"+dateStr);
        selectSort(arr1);

        Date date1 = new Date();
        SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr1 = format1.format(date1);
        System.out.println("排序前的时间:"+dateStr1);

得到的代码结果为:
在这里插入图片描述
可以看到这里排序的时间只有3秒,比冒泡排序快了很多.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值