小白学算法2.3——插入排序

来源:互联网 发布:java web php 编辑:程序博客网 时间:2024/06/03 14:41

小白学算法2.3——插入排序

标签: 小白学算法


1.插入排序算法

插入排序属于初级排序,时间复杂度为O(n2)n个数进行插入排序,需要n-1次排序,每次排序交换的次数取决于待排序的数列本身。插入排序假设最左边的数是最小的数,然后向右遍历,如果第二个数比第一个数小,则交换两个数的位置,反之不交换,结果是前两个数组成有序数列。继续向右遍历,如果第三个数比第二个数小,则交换第二个数和第三个数的位置,继续比较新的第二个数和第一个数,如果新的第二个数比第一个数小,则交换其位置,反之不交换,结果是前三个数组成有序数列

以此类推,在第i-1次排序中,前i个数组成的数列有序,只需要把第i+1个数插入到前面有序数列中的合适位置,使得前i+1个数组成的数列依旧有序即可。遍历完数列,排序也就完成了。

现在使用插入排序对数列{5, 7, 1, 4, 2}进行排序:

  • i表示排序的次数,j表示某次排序比较的两个数中较大的下标
  • 黄色表示本次比较发生交换的两个数

2.插入排序实现

void insertionSort(int* A, int n) {    for (int i=1; i<n; i++)        for (int j=i; j>0 && A[j]<A[j-1]; j--)            swap(A, j, j-1);}

3.插入排序改进

有一个方法可以大幅度的减少插入排序所消耗的时间,那就是减少元素访问的次数,只需要在内循环中将较大的元素向右移动而不是交换两个元素,就能使访问数组的次数减半。

//插入排序改进版void insertionSort(int* A, int n) {    for (int i=1; i<n; i++)    {        int insertData = A[i];        for (int j=i; j>0 && insertData<A[j-1]; j--)            A[j] = A[j-1];        A[j] = insertData;//for循环执行一次j--后才跳出,所以插入位置为j-1+1    }}

4.总结

  • 插入排序的i从1开始,因为第0个数自己组成的数列是有序的
  • 插入排序是稳定排序
  • 对于随机排序的无重复主键的数列,插入排序和选择排序的运行时间是平方级别的,两者之比应该是较小的常数,且看后续文章详解
  • 插入排序的时间取决于输入的数列,输入的序列有序性越高所消耗的时间就越少,插入排序经过优化就是希尔排序
  • 选择排序属于初级排序,时间复杂度为O(n2),当数据量较大时,建议采用高级排序
1 0
原创粉丝点击