十大经典排序算法 ( 三 ) 插入排序

介绍 : 

  插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法  。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增 1 的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。

算法原理 :

  1. 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

  2. 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面)

动图演示 :

算法稳定性 :

  如果待排序的序列中存在两个或两个以上具有相同关键词的数据,排序后这些数据的相对次序保持不变,即它们的位置保持不变,通俗地讲,就是两个相同的数的相对顺序不会发生改变,则该算法是稳定的;如果排序后,数据的相对次序发生了变化,则该算法是不稳定的。关键词相同的数据元素将保持原有位置不变,所以该算法是稳定的 。

时间复杂度 :

  在插入排序中,当待排序数组是有序时,是最优的情况,只需当前数跟前一个数比较一下就可以了,这时一共需要比较 N- 1 次,时间复杂度为 O(n) 。

  最坏的情况是待排序数组是逆序的,此时需要比较次数最多,总次数记为:1+2+3+…+N-1,所以,插入排序最坏情况下的时间复杂度为 O(n2) 。

  平均来说,A[1.. j-1] 中的一半元素小于 A[ j ] ,一半元素大于 A[ j ] 。插入排序在平均情况运行时间与最坏情况运行时间一样,是输入规模的二次函数 。

空间复杂度 :

  插入排序的空间复杂度为常数阶  。

应用场景 :

  插入排序适用于已经有部分数据已经排好,并且排好的部分越大越好。
  一般在输入规模大于 1000 的场合下不建议使用插入排序 。
 
Java代码 :
package com.algorithm.sort;

/**
 * 插入排序
 */
public class InsertionSort {
    public static void sort(int[] arr) {
        // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
        for (int i = 1; i < arr.length; i++) {
            // 记录要插入的数据
            int tmp = arr[i];
            // 从已经排序的序列最右边的开始比较,找到比其小的数
            int j = i;
            while (j > 0 && tmp < arr[j - 1]) {
                arr[j] = arr[j - 1];
                j--;
            }
            // 存在比其小的数,插入
            if (j != i) {
                arr[j] = tmp;
            }
        }
    }
}

 

 
posted on 2020-08-26 16:09  法哈席基  阅读(543)  评论(0编辑  收藏  举报