经典排序算法(二)--- 直接插入排序

直接插入排序

直接插入排序(Straight Insertion Sort)是一种最简单的排序方法,其基本操作是将一条记录插入到已排好的有序表中,从而得到一个新的、记录数量增1的有序表

算法原理

每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从后向前扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程

复杂度及稳定性
平均时间复杂度 最优时间复杂度 最坏时间复杂度 空间复杂度 稳定性
O(N^2) O(N) O(N^2) O(1) 稳定
动画演示

经典排序算法(二)--- 直接插入排序_第1张图片

视频演示

经典排序算法(二)--- 直接插入排序_第2张图片

代码实现
  1. python

    # 利用Python list的insert方法,如果需要倒序,只需将array[j] >= current改为小于即可
    def insert_sort(array):
        for i in range(1, len(array)):
            current = array[i]
            for j in range(i):
                if array[j] >= current:
                    array.insert(j, current)
                    array.pop(i+1)
                    break
        return array
     # 直接移动元素的方法,如果需要倒序,只需将array[pre_index] > current 改为小于即可
     def insert_sort2(array):
        for i in range(1, len(array)):
            pre_index = i-1
            current = array[i]
            while pre_index >= 0 and array[pre_index] > current:
                array[pre_index+1] = array[pre_index]
                pre_index -= 1
            array[pre_index+1] = current
        return array
    print(insert_sort([2, 4,3,10,9, 1, 8, 5, 5]))
    print(insert_sort2([2, 4,3,10,9, 1, 8, 5, 5]))
    # [1, 2, 3, 4, 5, 5, 8, 9, 10]
    
  2. java

    static int[] insertSort(int[] listData){
        for(int i=1;i< listData.length; i++){
            int current = listData[i];
            int j = i - 1;
            while (j >= 0 && current <=listData[j]){
                listData[j+1] = listData[j];
                j --;
            }
            listData[j+1] = current;
        }
        return listData;
    }
    // 查看输出,如果需要倒序,则将current <=listData[j]改为大于即可
    public static void main(String[] args) {
        int[] test = insertSort(new int[]{2, 4,3,10,9, 1, 8, 5, 5});
        for (int i: test) {
            System.out.println(i);
        }
    }
    // [1, 2, 3, 4, 5, 5, 8, 9, 10]
    
算法优化

直接插入排序还有一种改进算法,叫做折半插入排序,比直接插入算法明显减少了关键字之间比较的次数,因此速度比直接插入排序算法快,但记录移动的次数没有变,所以折半插入排序算法的时间复杂度仍然为O(n^2),与直接插入排序算法相同 。首先找好待排元素在已排好序列表中的插入位置,然后移动元素插入。

  1. python

    # 利用insert的方法,反序将array[middle] > current改为小于
    def insert_sort(array):
        for i in range(0, len(array)):
            current = array[i]
            low = 0
            high = i
            while low <= high:
                middle = (low + high) // 2
                if array[middle] > current:
                    high = middle - 1
                else:
                    low = middle + 1
            array.insert(low, current)
            array.pop(i+1)
        return array
    # 直接移动的方法,反序将array[middle] > current改为小于
    def insert_sort2(array):
        for i in range(0, len(array)):
            pre_index = i-1
            current = array[i]
            low = 0
            high = i
            while low <= high:
                middle = (low + high) // 2
                if array[middle] > current:
                    high = middle - 1
                else:
                    low = middle + 1
            for j in range(low, i):
                array[pre_index+1] = array[pre_index]
                pre_index -= 1
            array[pre_index + 1] = current
        return array
    print(insert_sort([2, 4,3,10,9, 1, 8, 5, 5]))
    print(insert_sort2([2, 4,3,10,9, 1, 8, 5, 5]))
    # [1, 2, 3, 4, 5, 5, 8, 9, 10]
    
  2. java

    static int[] insertSort(int[] listData){
        for(int i=1;i< listData.length; i++) {
            int current = listData[i];
            int low = 0;
            int high = i;
            int pre_index = i - 1;
            while (low <= high){
                int middle = (low + high) / 2;
                if (listData[middle] > current){
                    high = middle -1;
                }else {
                    low = middle + 1;
                }
            }
            for(int j = low; j< i;j++){
                listData[pre_index +1] = listData[pre_index];
                pre_index -= 1;
            }
            listData[pre_index+1] = current;
        }
            return listData;
    }
    // 查看输出,反序将listData[middle] > current改为小于
    public static void main(String[] args) {
        int[] test = insertSort(new int[]{2, 4,3,10,9, 1, 8, 5, 5});
        for (int i: test) {
            System.out.println(i);
        }
    }	
    

你可能感兴趣的:(经典算法)