• 排序-InsertSort


    数据结构之插入排序

    参考----王道论坛2015年数据结构联考复习指南----

      算法稳定性:如果待排序表中有任意两个元素x1,x2相等,且排序前x1在x2的前面,使用某个排序算法之后,若x1仍然在x2的前面,则这个排序算法是稳定的.

    一. 插入排序

    • 直接插入排序:最直观最简单的排序,适用于顺序存储和链式存储的线性表.
    • 折半插入排序:用了折半查找的排序,减少了元素的比较次数.
    • 希尔排序:又称为缩小增量排序.
    1. 直接插入排序

        实现将元素L(i)插入到已经有序的子序列L[1...i-1],中,需要执行:

          (1)查找L(i)在L[1...i-1]中的插入位置k.

          (2)将L[k...i-1]中的所有元素后移一位.

          (3)将L(i)复制到L(k).

        时间复杂度:O(n2),空间复杂度:O(1),稳定,算法代码如下:

     1 void InsertSort(ElemType A[], int n)
     2 {
     3     int i,j;
     4     for (i=2;i<=n;i++)
     5     {
     6         if (A[i]<A[i-1])
     7         {
     8             A[0]=A[i];
     9             for (j=i-1;A[0]<A[j];--j)
    10                 A[j+1]=A[j];
    11             A[j+1]=A[0] 
    12         }
    13     }
    14 }
      2. 折半插入

        与直接插入类似,不同的是先找到(折半查找)要插入的位置,在移动插入点之后的所有元素.

          时间复杂度为O(n2),空间复杂度O(1),稳定,算法代码如下:

     1 void InsertSort(ElemType A[],int n)
     2 {
     3     int i,j,low,high,mid;
     4     for (i=2;i<=n;i++)
     5     {
     6         A[0]=A[i];
     7         low=1;high=i-1;
     8         while(low<=high) //查找位置
     9         {
    10             mid=(low+high)/2;
    11             if (A[mid]>A[0])
    12                 high=mid-1;
    13             else
    14                 low=mid+1;
    15         }
    16         for (j=i-1;j>=high+1;--j)
    17         {
    18             A[j+1]=A[j]; //移动元素
    19         }
    20         A[high+1]=A[0];
    21     }
    22 }
      3. 希尔排序

        直接插入排序适用于基本有序的排序表和数据量不大的排序表,基于此,出现了希尔排序,又称缩小增量排序.

        基本思想:先将待排序表分割成若干形如L[i,i+d,i+2d...i+kd]的特殊子表,分别进行直接插入排序,直到整个表已经是基本有序,再对全体进行一次直接插入排序.

        流程如下:先取一个小于n的步长d1,把表中的全部记录分成d1个组,所有距离为d1的倍数的记录放在同一个组中,在各组中进行直接插入排序;然后取第二个步长d2<d1,重复上述过程,直到dt=1,即所有记录放在同一组中,再进行直接插入排序,希尔提出的增量序列为d1=n/2;di+1=floor(di/2),(floor:向下取整函数),并且最后一个增量为1.

        时间复杂度:最坏情况下为O(n2),空间复杂度为O(1),不稳定,算法代码如下:

     1 void ShellSort(ElemType A[],int n)
     2 {
     3     int dk,i,j;
     4     //前后记录位置的增量是dk,不是1
     5     for (dk=n/2;dk>=1;dk=dk/2)
     6     {
     7         for (i=dk+1;i<=n;++i)
     8         {
     9             if (A[i]<A[i-dk])
    10             {
    11                 A[0]=A[i];
    12                 for (j=i-dk;j>0 && A[0]<A[j];j-=dk)
    13                     A[j+dk]=A[j];
    14                 A[j+dk]=A[0];
    15             }
    16         }
    17     }
    18 }

    参考书目:

    王道考研系列

    高分笔记系列

  • 相关阅读:
    二级域名配置
    环信框架-消息模块
    屏幕适配问题
    iOS-NSSession
    环信框架使用
    静态UITableView
    __weak存在的问题
    MVVM与MVC
    iOS通知与多线程
    block
  • 原文地址:https://www.cnblogs.com/qi-yuan-008/p/9497168.html
Copyright © 2020-2023  润新知