数据结构与算法学习笔记——排序算法(二):选择排序

1、介绍

选择排序(select sorting)属于内部排序法,是从欲排序的数据中,按指定的规则选出某一元素,再依规定交换位置后达到排序的目的。

2、算法分析

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

说明:

(1)一共有数组大小 -1轮排序

(2)每一轮排序中:1)先假定当前这个数为最小数

                                   2)然后与后面的数依次比较,发现有比当前数更小的数,就重新确定最小数和下标

                                   3)当遍历到数组最后时,就得到本轮最小数和下标

3、代码实现

package com.czq.algorithm;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/**
 * 选择排序
 *
 * @author czq
 * @date 2020/07/16
 */
public class SelectSort {

    public static void main(String[] args) {
        //测试排序的执行速度
        //创建要给 800000 个的随机的数组
        int[] arr = new int[800000];
        for (int i = 0; i < arr.length; i++) {
            // 生成一个[0, 8000000) 数
            arr[i] = (int) (Math.random() * 8000000);
        }
//        int arr[] = {8, 3, 2, 1, 7, 4, 6, 5};
        System.out.println("============排序前===============");
//        System.out.println("排序后:" + Arrays.toString(arr));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("排序前时间:" + sdf.format(new Date()));
        selectSort(arr);
        System.out.println("============排序后===============");
        System.out.println("排序前时间:" + sdf.format(new Date()));
//        System.out.println("排序后:" + Arrays.toString(arr));
    }

    /**
     * 选择排序分析方法
     *
     * @param arr 排序的原始数组
     */
    private static void selectSortAnalysis(int[] arr) {
        /*************************第1轮****************************/
        //临时中转变量
        int temp;
        //最小值下标
        int minIndex = 0;
        //找出最小值下标
        for (int i = 1; i < arr.length; i++) {
            if (arr[minIndex] > arr[i]) {
                //更新minIndex
                minIndex = i;
            }
        }
        //判断最初位置是否是最小值,若不是,则把最小值放入最初位置
        if (minIndex != 0) {
            temp=arr[minIndex];
            arr[minIndex] = arr[0];
            arr[0] = temp;
        }
        System.out.println("第 1 轮后:" + Arrays.toString(arr));

        /*************************第2轮****************************/
        minIndex = 1;
        //找出最小值
        for (int i = 2; i < arr.length; i++) {
            if (arr[minIndex] > arr[i]) {
                //更新minIndex
                minIndex = i;
            }
        }
        //判断最初位置是否是最小值,若不是,则把最小值放入最初位置
        if (minIndex != 1) {
            temp=arr[minIndex];
            arr[minIndex] = arr[1];
            arr[1] = temp;
        }
        System.out.println("第 2 轮后:" + Arrays.toString(arr));
    }

    /**
     * 选择排序
     *
     * @param arr 排序的原始数组
     */
    private static void selectSort(int[] arr) {
        //临时中转变量
        int temp;
        //最小下标
        int minIndex;
        //循环选择
        for (int i = 0; i < arr.length - 1; i++) {
            //假定当前位置为最小值
            minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                //当前位置不是最小值时,更新minIndex的值
                if (arr[minIndex] > arr[j]) {
                    minIndex = j;
                }
            }
            //判断最初位置是否是最小值,若不是,则把最小值放入最初位置
            if (minIndex != i) {
                temp=arr[minIndex];
                arr[minIndex] = arr[i];
                arr[i] = temp;
            }
        }
    }
}

结果:80000长度的数组排序时间需要3秒,时间复杂度O(n2),空间复杂度O(1)

800000长度的数组排序时间需要3~4分钟

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值