zoukankan      html  css  js  c++  java
  • 排序算法之插入排序

    插入排序算法简介:

        有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外,而第二部分就只包含这一个元素。在第一部分排序后,再把这个最后元素插入到此刻已是有序的第一部分里的位置

    插入排序算法思想:

      一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:

    1. 从第一个元素开始,该元素可以认为已经被排序
    2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
    3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
    4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
    5. 将新元素插入到该位置后
    6. 重复步骤2~5

    插入排序算法模拟:

      

    这是我手画的,粗糙之处还请谅解!上面就是对初始数据:10,3,7,20,9,12进行的一次插入排序过程。黄色部分总是已排序好的序列,而蓝色部分是正要排序的,白色的是待排序的!

    插入排序参考代码:

     1 //插入排序
     2 //for j = 2 to A.length    
     3 //    key = A[j];
     4 //    //Insert [j] into the sorted sequence A[1,j - 1]
     5 //    i = j - 1;
     6 //  while i > 0 and A[i] > key
     7 //        A[i+1] = A[i];
     8 //        i = i -1;
     9 //    A[i + 1] = key
    10 
    11 void inserSort(int iarr[],int len)
    12 {
    13     int i,j,key;
    14     for(i = 1; i < len; ++i)
    15     {
    16         key = iarr[i];
    17         /*for(j = i - 1; j >=0 ; --j)
    18         {
    19             if(key < iarr[j])
    20                 iarr[j + 1] = iarr[j];
    21             else
    22                 break;
    23         }
    24         */
    25         j = i - 1;
    26         while(j >= 0 && key < iarr[j])
    27         {
    28             iarr[j + 1] = iarr[j];
    29             j--;
    30         }
    31         iarr[j + 1] = key;
    32     }
    33 }
    34 int main()
    35 {
    36     int a[10]={4,1,3,2,16,9,10,14,8,7};
    37     inserSort(a,10);
    38     for(int i=0;i < 10; ++i)
    39         cout << a[i] << " ";
    40     return 0;
    41 }

    插入排序复杂度分析

      时间复杂度:插入排序要用两个循环,最坏情况初始状态为逆序的时要进行复杂度为O(n^2)的比较和移动。故最坏的时间复杂度为O(n^2).当数据的初试状态为正序时,只需要比较复杂度为O(n)次,不用移动。此时最好的时间复杂度为O(n)。所以插入排序适合初始状态基本有序的情况。

      空间复杂度:插入排序是就地排序,所以空间复杂度是O(1).

      是否是稳定排序:稳定的!

      插入排序有个升级版,那就是二分法插入排序。折半插入排序算法是一种稳定的排序算法,比直接插入算法明显减少了关键字之间比较的次数,因此速度比直接插入排序算法快,但记录移动的次数没有变,所以折半插入排序算法的时间复杂度仍然为O(n^2),与直接插入排序算法相同。附加空间O(1)

      参考代码如下:(真的只是参考)

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 void binInserSort(int iarr[],int len)
     6 {
     7     int i,j,key,low,high,mid;
     8     for(i = 1; i < len; ++i)
     9     {
    10         j = i - 1;
    11         key = iarr[i];
    12         low = 0;
    13         high = i - 1;
    14         while(low <= high)
    15         {
    16             mid = ( low + high ) / 2;
    17             if(key > iarr[mid])
    18                 low = mid + 1;
    19             else
    20                 high = mid - 1;
    21         }
    22         //跳出while的时候,low == high,就是插入的位置
    23         while(j >= high + 1)
    24         {
    25             iarr[j + 1] = iarr[j];
    26             j--;
    27         }
    28         iarr[j + 1] = key;
    29     }
    30 }
    31 int main()
    32 {
    33     int a[25]={4,1,3,2,16,9,10,14,8,7,7,10,7,28,30,3,12,0,1,3,9,12,11,4,19};
    34     binInserSort(a,25);
    35     for(int i=0;i < 25; ++i)
    36         cout << a[i] << " ";
    37     return 0;
    38 }
  • 相关阅读:
    [转]跨语言通信方案比较
    C#三种定时器
    Java优化技巧
    websocket初探
    [转]远远走来一个绿茶婊
    赠与今年的大学毕业生-----------胡适
    HDU3068 回文串 Manacher算法
    OpenCV安装与配置
    tkinter事件机制
    哈夫曼压缩
  • 原文地址:https://www.cnblogs.com/zhuwbox/p/3631651.html
Copyright © 2011-2022 走看看