複習一:陣列(4)-插入排序

耳冉鵝發表於2020-09-25

插入排序是一種簡單的排序方法。
思路:
每一步將一個待排序的資料插入到前面已經排好序的有序序列中,直到插完所有元素為止。
在這裡插入圖片描述
演算法實現:
直接插入排序是將無序序列中的資料插入到有序的序列中,在遍歷無序序列時,首先拿無序序列中的首元素去與有序序列中的每一個元素比較並插入到合適的位置,一直到無序序列中的所有元素插完為止。

public class insertSort {
    public static void main(String[] args) {
        int [] arr = {2,6,65,82,35,5,91,46};
        System.out.println("原arr陣列:"+ Arrays.toString(arr));
        for(int i=1;i<arr.length;i++){
            for(int j=i-1;j>=0&&arr[j]>arr[j+1];j--){
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
        System.out.println("插入排序後的arr:"+Arrays.toString(arr));
    }
}

執行結果:
在這裡插入圖片描述

時間複雜度: O(n²)
穩定性: 穩定
插入排序是穩定的排序演算法,滿足條件arr[j] > arr[j + 1]才發生交換,這個條件可以保證值相等的元素的相對位置不變。

優化:
上面的演算法的缺點:在第i-1趟插入時,需要把第i個元素插入到前面的i-1個元素中,該演算法總是從i-1個元素開始逐個比較之前的每個元素,直到找到第i個元素的插入位置,這顯然沒有利用前面0~i-1個元素已經有序的特點。
優化:在0~i-1個有序元素給第i個元素尋找插入的位置時,使用二分查詢法可以有效提高查詢插入位置的時間效率,經過優化的插入排序稱為折半插入排序,折半插入排序的時間複雜度為O(n*logn)

public class binaryInsertSort {
    public static void main(String[] args) {
        int [] arr = {2,6,65,82,35,5,91,46};
        System.out.println("原arr陣列:"+ Arrays.toString(arr));
        int j; // 內迴圈的j不能是區域性變數,否則陣列後面的較小數(5)將覆蓋arr陣列中間的部分
        for(int i=1;i<arr.length;i++){
            int temp = arr[i];
            // L為有序部分陣列的左值,R為有序部分陣列的右值
            int L = 0,R = i-1;
            // mid 為有序部分陣列的中值
            int mid;
            while(L<=R){
                mid = (L+R)/2;
                if(arr[mid]>temp){
                    R =mid-1;
                }else {
                    L =mid+1;
                }
            }
            for(j=i-1;j>=R+1;j--){
                arr[j+1] = arr[j];
            }
            arr[j+1] = temp;
        }
        System.out.println("插入排序後的arr:"+Arrays.toString(arr));
    }
}

執行結果:
在這裡插入圖片描述

相關文章