luliyu-java-day16

选择排序(Selection-Sort)

先把最小的拿出来
剩下的, 再把最小的拿出来
剩下的, 再把最小的拿出来
。。。
每次选择还没处理的元素里最小的元素

选择排序就是重复“从待排序的数据中寻找最小值,将其与序列最左边的数字进行交换”这一操作的算法。在序列中寻找最小值时使用的是线性查找。

比如: 对数字1~9进行排序。 使用线性查找在数据中寻找最小值,于是我们找到了最小值 1
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
先找到一个最小值索引

public class SelectionSort {
    private SelectionSort(){};
    public static void sort(int[] arr){
        int minIndex=0;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] < arr[minIndex])
                minIndex = i;
        }
        System.out.println(minIndex);
    }
    public static void main(String[] args) {
        int[] arr = { 4, 2, 3, 6, 1, 5};
        for(int e: arr)
            System.out.print(e + " ");
        System.out.println();
        SelectionSort.sort(arr);
        for(int e: arr)
            System.out.print(e + " ");
    }

}

无外层循环操作

public class SelectionSort0 {
    private SelectionSort0(){};
    public static void sort(int[] arr){
        int minIndex=0;
        for ( int j = 0; j < arr.length; j++) {
            if (arr[j] < arr[minIndex])
                minIndex =j;
        }
        System.out.println("minIndex = " + minIndex);
        swap(arr, 0, minIndex);
        for(int e: arr)
            System.out.print(e + " ");
        System.out.println();
        System.out.println("----------------------");
        minIndex=1;
        for ( int j = 1; j < arr.length; j++) {
            if (arr[j] < arr[minIndex])
                minIndex =j;
        }
        System.out.println("minIndex = " + minIndex);
        swap(arr, 1, minIndex);
        for(int e: arr)
            System.out.print(e + " ");
        System.out.println();
        System.out.println("----------------------");

        minIndex=2;
        for ( int j = 2; j < arr.length; j++) {
            if (arr[j] < arr[minIndex])
                minIndex =j;
        }
        System.out.println("minIndex = " + minIndex);
        swap(arr, 2, minIndex);
        for(int e: arr)
            System.out.print(e + " ");
        System.out.println();
        System.out.println("----------------------");
    }
    private static void swap(int[] arr, int i, int minIndex){
        int temp = arr[i]; arr[i] = arr[minIndex];arr[minIndex] = temp;
    }
    public static void main(String[] args) {
        int[] arr = { 4, 3, 6, 1, 5, 2};
        for(int e: arr)
            System.out.print(e + " ");
        System.out.println();
        SelectionSort0.sort(arr);
//        for(int e: arr)
//            System.out.print(e + " ");
    }

}

完整代码

public class SelectionSort {
    private SelectionSort() {
    }

    ;

    public static void sort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            int minIndex = i;
            for (int j = i; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) minIndex = j;
            }
            swap(arr, i, minIndex);
        }
    }

    private static void swap(int[] arr, int i, int minIndex) {
        int temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }

    public static void main(String[] args) {
        int[] arr = {4, 3, 6, 1, 5, 2};
        for (int e : arr)
            System.out.print(e + " ");
        System.out.println();
        SelectionSort.sort(arr);
        for (int e : arr)
            System.out.print(e + " ");
    }

}

选择排序使用了线性查找来寻找最小值,因此在第 1 轮中需要比较 n -1 个数字,第
2 轮需要比较 n -2 个数字……到第 n -1 轮的时候就只需比较 1 个数字了。因此,总的比
较次数与冒泡排序的相同,都是 (n-1)+(n-2)+…+1 ≈ n2/2 次。每轮中交换数字的次数最多为 1 次。如果输入数据就是按从小到大的顺序排列的,便不需要进行任何交换。选择排序的时间复杂度为 O(n2)。

复杂度分析

表示算法的性能

常见算法复杂度分析

  • 线性查找法 —> O (n)
  • 一个数组中元素可以组成那些数据对 —> O (n^2)
  • 遍历二维数组 —> O (n^2)
  • log(n)
    举例: 二分搜索
    在最好情况下二分搜索的时间复杂度是 O(1),最坏情况(平均情况)下 O(log n),我们直接来看最坏情况下的例子。已知有 16 个元素的有序数组。
    举个最坏情况的例子,比如我们要找的是数字 13。


    选中间的元素作为中心点(长度的一半)

    13 小于中心点,所以不用考虑数组的后一半

    重复这个过程,每次都寻找子数组的中间元素


    每次和中间元素比较都会使搜索范围减半。

所以为了从 16 个元素中找到目标元素,我们需要把数组平均分割 4 次,也就是说,


  • 求约数 — 》O (n)

  • 根号O ( n)

  • 长度为 n的二进制数字 O(2^n)

  • 长度为 n的数组的所有排列 O(n!)

  • 判断数字是否为偶数 O(1)
    复杂度计较

O(1)  < O(logn) < O(根号n) < O(n) < O(nlogn)< O(n^2) < O(2^n) < O(n!)

空间复杂度和时间复杂度同理

更改代码为泛型支持

在Java中的类比较必须实现 Comparable接口
编写实现 Comparable接口的实体类Student

import java.util.Objects;

/**
 * @ Author     :Eric Lee
 * @ Date       :Created in 11:35 2021/8/14
 * @ Description:
 * @ Modified By:
 * @ Version    : 1.0
 */
public class Student implements Comparable<Student> {
    private String name;
    private Integer score;
    private Double height;
    public Student() {
    }

    public Student(String name, Integer score, Double height) {
        this.name = name;
        this.score = score;
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }

    public Double getHeight() {
        return height;
    }

    public void setHeight(Double height) {
        this.height = height;
    }

    @Override
    public String toString() {
        return "Student{" + "name='" + name + '\'' + ", score=" + score + ", height=" + height + '}';
    }

    @Override
    public int compareTo(Student o) {
        // 分数比较
//        if (this.score < o.score)
//            return -1;
//        else if (this.score == o.score)
//            return 0;
//        return 1;
//        return this.score - o.score; //升序
        return o.score - this.score ;  //降序
    }
}

更改为泛型支持并测试

/**
 * @ Author     :Eric Lee
 * @ Date       :Created in 11:37 2021/8/14
 * @ Description:
 * @ Modified By:
 * @ Version    : 1.0
 */
public class SelectionSort {
    private SelectionSort() {
    }
    public static <E extends Comparable<E>> void sort(E[] arr) {
        for (int i = 0; i < arr.length; i++) {
            int minIndex = i;
            for (int j = i; j < arr.length; j++) {
                // j 位置 - minIndex 位置 小于0 证明j位置更小
                if (arr[j].compareTo(arr[minIndex]) < 0)
                    minIndex = j;
            }
            swap(arr, i, minIndex);
        }
    }
    private static <E> void swap(E[] arr, int i, int minIndex) {
        E temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }

    public static void main(String[] args) {
        Student[] students = data();
        for (Student s: students) {
            System.out.println(s);
        }
        System.out.println("---------------------------------");
        SelectionSort.sort(students);
        for (Student s: students) {
            System.out.println(s);
        }
    }
    public static Student[] data(){
        Student s1 = new Student("张三", 23, 1.6);
        Student s2 = new Student("李思", 43, 1.9);
        Student s3 = new Student("王五", 12, 1.4);
        Student s4 = new Student("赵六", 11, 1.5);
        Student s5 = new Student("田七", 52, 1.8);
        Student[] stus = new Student[5];
        stus[0] = s1;
        stus[1] = s2;
        stus[2] = s3;
        stus[3] = s4;
        stus[4] = s5;
        return stus;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值