排序算法3---插入排序

Posted 干货频道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法3---插入排序相关的知识,希望对你有一定的参考价值。

前面我们分析了两种比较排序,冒泡排序和选择排序,这一节我们继续分析另一种比较排序---插入排序

冒泡排序、选择排序都有比较操作和交换操作,而插入排序将交换操作优化为移动操作,没有对两个元素直接进行交换操作。交换操作有三次赋值,而移动操作只有一次赋值,这也正是插入排序优于冒泡排序的原因

插入排序的核心操作就是将一个数据插入到已经排好序的有序组中,得到一个新的,个数加1的有序组,相应的无序组个数减1。

算法原理


将原始数组分为有序组(第一个元素)和无序组(剩下的 N-1 个元素);

从无序组取出第一个元素作待插入元素,在有序组中从后向前比较,将比待插入元素大的数据向后移动一个位置,重复操作,直到碰到小于或等于待插入元素的数据,然后将待插入元素插入此位置

重复上一步,直到整个数组变为有序组。


算法分析


下面用从网上选的一个动图来分析插入排序,个人觉得这个动图非常形象、直观,可以让我们很容易的理解插入排序的原理。

注:下图选自网络,在此感谢此图作者。

分析:从上面的动画我们可以看出整个数组被分为两部分,一部分是有序组用黄色标识,一部分是无序组用蓝色标识(第一次循环,第一个数据作有序组,剩下 N-1 个数据作无序组)。每次从无序组取出第一个元素,然后从有序组的后面向前面比较,将比待插入元素大的数据向后移动,直到碰到小于或等于待插入元素的数据,最后将待插入元素插入相应位置。重复以上操作,有序组个数不断加一,无序组个数不断减一,直到所有元素成为有序组。


算法实现


根据上面的排序分析,我们实现以下算法。


// 插入排序

void insertion_sort(int *arr, int n)

{

        int i = 0, j = 0;

int val = 0;

for(i=1; i<n; i++)

        {

val = arr[i];

j = i - 1;

while( j >= 0 && arr[j] > val )

{

arr[j+1] = arr[j];

j--;

}

arr[j+1] = val;

}

}


算法改进


插入排序从后向前比较,每次数据只能移动一个位置,这样效率比较低,后来有人就在这个步进上做文章,提出了“缩小增量排序”,这个人就是希尔,因此得名希尔排序。后面我们用单独一节来分析希尔排序。


算法性能


时间复杂度

插入排序的平均时间复杂度为o(n2),最优时间复杂度为o(n),最差时间复杂度为o(n2)。


空间复杂度

插入排序的空间复杂度为 o(1)。每次从无序组中取出待插入有序组的元素,需要开辟一个空间存放此待插入元素,与数组规模无关,所以插入排序的空间复杂度为o(1)。


稳定性

插入排序是一种稳定的排序算法。插入排序是从后向前比较,按需移动位置,然后插入,如果有两个相等的元素时,上述操作不会改变相同元素的前后顺序,因此插入排序是稳定的。


github源码连接:https://github.com/yqwung/sort



以上是关于排序算法3---插入排序的主要内容,如果未能解决你的问题,请参考以下文章

算法——排序——插入排序——希尔排序

《算法》笔记 3 - 选择排序插入排序希尔排序

排序算法3--插入排序--希尔排序(缩小增量排序)

排序算法总结

排序算法总结

排序算法总结