插入排序终极解析

155 阅读2分钟

这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

插入排序基本思想

插入排序与打牌时的理牌过程很像,每次从一堆杂乱的牌组的最顶部抽一张随机的牌,然后将其从左到右与手上的牌进行对比,找到它应该待的位置后把它放置在那里。

算法基本思想

  1. 从数组待排序部分取出一个元素
  2. 将其与已经排好的部分从左到右或从右到左进行对比
  3. 对比大小,直至找到左边大于等于该元素,右边小于等于该元素(或反过来)的地方 4.将元素插入到这个地方

复杂度解析

插入排序的最好时间复杂度为O(N),在最好的情况下,数组已经是被排好序的了,只需要遍历一次,验证数组的有序性就行。
最差的时间复杂度为O(N^2),数组是完全逆序的,需要把每一个元素进行一遍循环查找,需要用到两次遍历查询,因此,这种算法的时间效率并不是很高。有很大的偶然性,一般只用在排列数据较少的情况下

因为堆排序是就地排序,没有递归也就没有占据多余空间,所以空间复杂度是O(1)

稳定性解析

假定在待排序的记录序列中,存在多个具有相同的关键字的记录,经过排序过后,这些记录的相对次序保持不变

即在原序列中,Ri = Rj, 且Ri在Rj之前,而在排序后 的序列中,Ri仍在Rj之前则称这种排序算法是稳定的,否则则称其为不稳定的
考虑序列{9, 5a, 7, 5b },按照堆排序的算法走一遍,很快就能发现,输出序列为{5b, 5a, 7, 9},而且与等号无关,显然可见堆排序是不稳定的

使用场景解析

因为在二重循环时,数据在刚刚满足条件时就可以被放置下来,所以不会发生与它相同的数据位置改变的现象。即该算法可以使排序前后,两个相同的数的相对位置不发生改变,该算法为稳定的。

代码实现

JavaScript实现

var len;

function insertSort(arr) {
    var len =arr.length;
    for (var i=1;i<len; i++) {
        var temp=arr[i];
        var j=i-1;//默认已排序的元素
        while (j>=0 && arr[j]>temp) {  //在已排序好的队列中从后向前扫描
                arr[j+1]=arr[j]; //已排序的元素大于新元素,将该元素移到一下个位置
                j--;
            }
        arr[j+1]=temp;
        }
    return arr
 }