挑戰七大排序算法-01直接插入排序

路人甲:嗨,你好,排小序,我想問你一個問題,好嗎?

排小序:好呀,你問吧,我知道很多關於排序的知識呢,只要你問,我都會告訴你呀

路人甲:問題來嘍,一個有序的數組,往裏面添加一個新的數據後,如何繼續保持數據有序呢?

排小序:嗯嘛嘛,這個嘛,是這樣的,很簡單,只要遍歷數組,找到數據應該插入的位置將其插入即可。怎麼樣,我厲害吧

路人甲:哇塞,你真棒。帶我學習排序吧(害羞)

針對以上排序的經典問題,我們這裏也提出一個經典排序算法,那就是,直接插入排序。

1.核心思想

已排序區間+未排序區間

取未排序區間中的元素,在已排序區間中找到合適的插入位置將其插入,並保證已排序區間數據一直有序。重複這個過程,直到未排序區間中元素爲空,算法結束。

2.算法描述過程

(1)從第一個元素開始,該元素可以認爲已經被排序;
(2)取出下一個元素,在已經排序的元素序列中從後向前掃描;
(3)如果該元素(已排序)大於新元素,將該元素移到下一個位置;
(4)重複步驟3,直到找到已排序的元素小於或者等於新元素的位置;
(5)將新元素插入到該位置後;
(6)重複步驟2-5

3.代碼實現

3.1直接插入排序代碼實現

public static void insertSort(int[] array){
        if(array.length <= 1){
            return;
        }else{
            for(int i = 1;i < array.length;i++){
                //有序區間:[0,i)
                //無序區間:[i,array.length)
                int value = array[i];
                int j = i-1;
                for(;j >= 0 && array[j] > value;j--){
                    array[j+1] = array[j];
                }
                array[j+1] = value;
            }
        }
    }

3.2接下來測試一下下

爲了檢測排序結果的重要性,可以通過Arrays.sort()內置方法來測試一下

public static void main(String[] args) {
        int[] a = {2,5,1,7,3,6,9};

        //將數組a克隆後賦給數組b
        int[] b = a.clone();
        insertSort(b);
        System.out.println(Arrays.toString(b));

        //通過Arrays.sort進行驗證排序結果
        int[] c = a.clone();
        Arrays.sort(c);
        System.out.println(Arrays.toString(c));

        System.out.println(Arrays.equals(b,c));
        
}

結果是這樣的:

哈,明顯的看出,我們的直接插入排序代碼實現是正確的(噓,真是優秀)

3.3測試一下排序速度

爲了更明顯的看出直接插入排序算法的性能,隨機生成10萬個數據的數組來測試排序速度

public static void testSpeed(){
        Random random = new Random(20191019);
        int[] a = new int[100000];
        for (int i = 0;i < 100000;i++){
            a[i] = random.nextInt(200000);
        }
        long begin = System.nanoTime();
        insertSort(a);
        long end = System.nanoTime();
        double s = (end-begin)/1000/1000/1000;
        System.out.printf("一共耗時:%.5f 秒%n",s);
}

運行後,會發現,竟然只要這麼短的時間,是不是提高了人工排序的效率呢?

好了,只要五秒就可以對10萬個數據進行排序,是不是很優秀呢?(是的,很棒呀)

期待留言或者分享呀

呀,忘記源代碼了,在這裏呀:

package sort.insertSort;

import java.util.Arrays;
import java.util.Random;

/**
 * @Author:Star
 * @Date:Created in 9:24 2019/10/19
 * @Description:直接插入排序
 * 時間複雜度:最好O(n)平均:O(n^2)最壞:(n^2)
 * 空間複雜度:O(1)(原地排序)
 * 穩定性:穩定
 */
public class Sort {
    public static void insertSort(int[] array){
        if(array.length <= 1){
            return;
        }else{
            for(int i = 1;i < array.length;i++){
                //有序區間:[0,i)
                //無序區間:[i,array.length)
                int value = array[i];
                int j = i-1;
                for(;j >= 0 && array[j] > value;j--){
                    array[j+1] = array[j];
                }
                array[j+1] = value;
            }
        }
    }

    public static void main(String[] args) {
        /*
        int[] a = {2,5,1,7,3,6,9};

        int[] b = a.clone();
        insertSort(b);
        System.out.println(Arrays.toString(b));

        //通過Arrays.sort進行驗證排序結果
        int[] c = a.clone();
        Arrays.sort(c);
        System.out.println(Arrays.toString(c));

        System.out.println(Arrays.equals(b,c));*/
        testSpeed();
    }

    public static void testSpeed(){
        Random random = new Random(20191019);
        int[] a = new int[100000];
        for (int i = 0;i < 100000;i++){
            a[i] = random.nextInt(200000);
        }
        long begin = System.nanoTime();
        insertSort(a);
        long end = System.nanoTime();
        double s = (end-begin)/1000/1000/1000;
        System.out.printf("一共耗時:%.5f 秒%n",s);
    }
}

一起進步,一起學習,加油加油

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章