数据结构与算法--Java--day02--LinearSearch及复杂度分析--选择排序

将测试时间改为秒级别

  // 一起测100万和1000万数据规模的测试
        int[] dataSize = {1000000, 10000000};
        // for each
//        for (临时变量数据类型 临时变量 :迭代对象){
//
//        }
        for (int n: dataSize){
            Integer[] data = ArrayGenerator.generateOrderedArray(n);
            long startTime = System.nanoTime();
            for (int i = 0; i < 100; i++)
                LinearSearch.search(data, n);
            long endTime = System.nanoTime();

            double time = (endTime-startTime)/1000000000.0;  //9个零
            System.out.println("n = " + n + ", 100 runs : "+ time + "s");
        }

选择排序(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 = {6, 1, 7, 8, 9, 3, 5, 4, 2};
        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 = {6, 1, 7, 8, 9, 3, 5, 4, 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 = {6, 1, 7, 8, 9, 3, 5, 4, 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)。

更改代码为泛型支持

在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;
    }
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值