1. 程式人生 > >Mint演算法初學—直接插入排序

Mint演算法初學—直接插入排序

直接插入排序

程式碼

package com.sort;

public class InsertSort {

    public static void main(String[] args) {
        System.out.println("------------------------------");
        int[] arg = {1, -9, 5, 8, 7, 6, 2, 4, 22, 24};
        System.out.println("插入排序前:");
        PrintArg(arg);
        System.out.println("------------------------------");
        InsertSort(arg);
        System.out.println("插入排序後:");
        PrintArg(arg);
        System.out.println("------------------------------");
    }

      //插入排序
//    public static void InsertSort(int[] arg) {
//        int length = arg.length;
//        for (int i = 1; i < length; i++) {
//            for (int j = i; j > 0 && smaller(arg[j], arg[j - 1]); j--) {
//                swap(arg, j, j - 1);
//            }
//        }
//    }
    //插入排序
    public static void InsertSort(int[] arg) {
        int length = arg.length;
        for (int i = 1; i < length; i++) {

            for (int j = i; j > 0; j--) {
                if (smaller(arg[j], arg[j - 1])) {
                    swap(arg, j, j - 1);
                } else {
                    break;
                }
            }
            System.out.println("第" + i+"次排序:");
            PrintArg(arg);
        }
        System.out.println("------------------------------");
    }

    //比較大小
    public static boolean smaller(int x, int y) {
        if (x < y) {
            return true;
        } else {
            return false;
        }
    }

    //交換順序
    public static void swap(int arg[], int i, int j) {
        int temp = arg[i];
        arg[i] = arg[j];
        arg[j] = temp;
    }

    //列印陣列
    public static void PrintArg(int[] arg) {
        for (int i = 0; i < arg.length; i++) {
            if (i == arg.length - 1) {
                System.out.println(arg[i]);
            } else {
                System.out.print(arg[i] + " ");
            }
        }
    }

}

執行結果

在這裡插入圖片描述

原理

插入排序的基本思想是:每一趟將一個待排序的記錄,按其關鍵字的大小插入到已經排好序的一組記錄的適當位置上,直到所有待排序記錄全部插入為止。

演算法分析

時間複雜度

從時間來看,排序的基本操作為:比較兩個關鍵字的大小和移動記錄。 對於其中的某一趟插入排序,內層的for迴圈次數取決於待插記錄的關鍵字與前i個關鍵字之間的關係。其中,在最好情況(正序:待排序序列中記錄按關鍵字非遞減有序排列)下,比較1次,不移動;在最壞情況(逆序:待排序序列中記錄按關鍵字非遞增有序排列)下,比較i次(依次同前面i-1個記錄進行比較,並和哨兵比較1次),移動i+1次(前面的i-1個記錄依次向後移動,另外開始時將待插入的記錄移動到監視哨中,最後找到插入位置,又從監視哨中移過去)。 對於整個排序過程需執行n-1趟,最好情況下,總的比較次數達最小值n-1,記錄不需移動;最壞情況下,宗的關鍵字比較次數KCN和記錄移動次數RMN均達到最大值,分別為: 在這裡插入圖片描述

若待排序序列中出現各種可能排列的概率相同,則可取上述最好情況和最壞情況的平均情況。在平均情況下,直接插入排序關鍵字的比較次數和記錄移動次數均約為n2/4。 由此,直接插入排序的時間複雜度為O(n2)。

空間複雜度

直接插入排序只需要一個記錄的輔助空間,所以空間複雜度為O(1)。

演算法特點

  1. 穩定排序。
  2. 演算法簡便,且容易實現。
  3. 也適用於鏈式儲存結構,只是在單鏈表上無需移動記錄,只需修改相應的指標。
  4. 更適合於初始記錄基本有序(正序)的情況,當初始記錄無序,n較大時,此演算法時間複雜度較高,不宜採用。

2018.10.17