【算法和数据结构】—— 1.选择排序、插入排序

来源:互联网 发布:linux高级编程 编辑:程序博客网 时间:2024/06/04 18:56
  • 1、O(n^2)排序算法之选择排序**
  • 2、O(n^2)排序算法之插入排序**

一、O(n^2)排序算法之选择排序

  • 1、实现思路: 从最左边下标开始,将该下标的元素和它右边所有元素比较,每一趟遍历找出最小元素的下标,然后将最小下标的元素和该下标元素互换,即每一趟遍历都将最小值放在开始遍历的最左的下标位置

  • 2、int类型数组的选择排序算法

package com.algorithm.demo;/** *  * @author eric * 从最左边下标开始,将该下标的元素和它右边所有元素比较,每一趟遍历找出最小元素的下标 * 然后将最小下标的元素和每一趟遍历开始的最左边下标的元素互换,即每一趟遍历都将最小值放在开始遍历的最左的下标位置 */public class SelectionSort {    // 我们的算法类不允许产生任何实例    private SelectionSort() {    }    public static void sort(int[] arr) { // 左边要比较到倒数第二个下标        int len = arr.length;        for (int i = 0; i < len - 1; i++) {            // 寻找[i, n)区间里的最小值的索引            int minIndex = i;            for (int j = i + 1; j < len; j++) {                // 每一趟遍历找出最小元素的下标                if (arr[j] < arr[minIndex]) {                    minIndex = j;                }            }            // 交换开始遍历的最左和最小下标的元素            swap(arr, i, minIndex);        }    }    /**     * 交换两个下标的元素     *      * @param arr 要排序的数组     * @param i 下标1     * @param j 下标2     */    private static void swap(int[] arr, int i, int j) {        int t = arr[i];        arr[i] = arr[j];        arr[j] = t;    }    public static void main(String[] args) {        int[] arr = { 10, 9, 8, 7, 6, 5, 4, 1, 2, 3, 0 };        SelectionSort.sort(arr);        for (int i = 0; i < arr.length; i++) {            System.out.print(arr[i]);            System.out.print(' ');        }        System.out.println();    }}
  • 3、实现了Comparable接口的类,支持泛型排序

    • 1、实现了Comparable接口的类

      package com.algorithm.demo;/** *  * @author eric * */// 实现了Comparable接口的类,支持排序public class Student implements Comparable<Student> {    private String name;    private int score;    public Student(String name, int score) {        this.name = name;        this.score = score;    }    // 定义Student的compareTo函数    // 如果分数相等,则按照名字的字母序排序    // 如果分数不等,则分数高的靠前    @Override    public int compareTo(Student that) {        if (this.score == that.score)            return this.name.compareTo(that.name);        if (this.score < that.score)            return 1;        else if (this.score > that.score)            return -1;        else // this.score == that.score            return 0;    }    // 定义Student实例的打印输出方式    @Override    public String toString() {        return "Student: " + this.name + " " + Integer.toString(this.score);    }}
    • 2、支持泛型排序实现类

      package com.algorithm.demo;public class SelectionSort2 {    // 我们的算法类不允许产生任何实例    private SelectionSort2(){}    /**     * 支持泛型比较     * @param arr     */    public static <T extends Comparable<T>> void sort(T[] arr){        int len = arr.length;        for (int i = 0; i < len - 1; i++) {            // 寻找[i, n)区间里的最小值的索引            int minIndex = i;            for (int j = i + 1; j < len; j++) {                // 使用compareTo方法比较两个Comparable对象的大小                if (arr[j].compareTo(arr[minIndex]) < 0) {                    minIndex = j;                }            }            swap(arr, i, minIndex);        }    }    private static void swap(Object[] arr, int i, int j) {        Object t = arr[i];        arr[i] = arr[j];        arr[j] = t;    }    public static void main(String[] args) {        // 测试Integer        Integer[] a = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };        SelectionSort2.sort(a);        for (int i = 0; i < a.length; i++) {            System.out.print(a[i]);            System.out.print(' ');        }        System.out.println();        // 测试Double        Double[] b = { 4.4, 3.3, 2.2, 1.1 };        SelectionSort2.sort(b);        for (int i = 0; i < b.length; i++) {            System.out.print(b[i]);            System.out.print(' ');        }        System.out.println();        // 测试String        String[] c = { "D", "C", "B", "A" };        SelectionSort2.sort(c);        for (int i = 0; i < c.length; i++) {            System.out.print(c[i]);            System.out.print(' ');        }        System.out.println();        // 测试自定义的类 Student        Student[] d = new Student[4];        d[0] = new Student("D", 90);        d[1] = new Student("C", 100);        d[2] = new Student("B", 95);        d[3] = new Student("A", 95);        SelectionSort2.sort(d);        for (int i = 0; i < d.length; i++)            System.out.println(d[i]);    }}

二、插入排序

  • 1、普通插入排序实现思路:从右边开始起将相邻元素两两比较后排序。第一趟将最左边两个元素比较排序,右边的大于(或小于)左边的话,两者调换元素位置;第二趟从最左边三个元素右边开始将两两比较排序,…… 最后一次是所有元素的相邻元素从右边开始将两两比较排序
for (int i = 1; i < len; i++) {    // 寻找元素arr[i]合适的插入位置    for( int j = i; j > 0 && arr[j].compareTo(arr[j-1]) < 0 ; j--) {        swap(arr, j, j-1);    }  }
  • 改进版插入排序:
    • 耗时改进点:每次两两比较后如果有需要都互换位置(耗时:交换每次都需要三次赋值操作,访问数组和访问相应下标的数组数据),改进后每次将每次都要交换操作变成有必要时一次赋值来节省时间
    • 实现思路:因为每一趟遍历排序后(0 —> i-1下标的元素已排好序); 下一趟开始遍历前先复制一份i 下标的元素,然后将i 下标元素和 i - 1 下标元素比较,没互换的需要,此趟直接排序完成(非常省时);如有需要互换,将 i - 1下标元素放到 i 下标位置,原复制出来的 i 下标元素值再和 i - 2下标元素比较,如有需要互换,将 i - 2 下标元素放到 i - 1 下标位置;没需要互换,将复制出来的 i 下标元素值放在 i - 1 下标位置,此趟排序完成 … 即上一趟排好序的数不断往前推, i 下标元素找到属于自己的位置, 就是每一趟排序完成。
int len = arr.length;for (int i = 1; i < len; i++) {          T e = arr[i];          int j = i; // j 保存元素e应该插入的位置          for( ; j > 0 && arr[j-1].compareTo(e) > 0 ; j--) {            arr[j] = arr[j-1]; // 前一趟排好序的数组和e值比较,不断往前推移          }          arr[j] = e;}
  • 时间复杂度:==> 对于几乎有序的数组,插入排序效果非常高,时间复杂度近乎O(n)
阅读全文
0 0
原创粉丝点击