• [排序算法] 插入排序(3种)


    1.直接插入排序

    【思想】利用有序表的插入操作进行排序

    有序表的插入:将一个记录插入到已排好序的有序表中,从而得到一个新的有序表

    【特点】稳定

    空间代价:O(1)  时间代价:O(n^2)

     1 void InsertSort (int Array[], int n)
     2 {
     3     //Array[]为待排序数组,n为数组长度
     4     int TempRecord;    // 临时变量
     5     for (int i = 1; i < n; i ++) // 依次插入第i个记录
     6     {
     7         TempRecord = Array[i];
     8         //从i开始往前寻找记录i的正确位置
     9         int j = i - 1;
    10         //将那些大于等于记录i的记录后移
    11         while ((j >= 0) && (TempRecord < Array[j]))
    12         {
    13             Array[j+1] = Array[j];
    14             j --;
    15         }
    16         //此时j后面就是记录i的正确位置,回填
    17         Array[j + 1] = TempRecord;
    18     }
    19 }

    2.折半插入排序

    【思想】

    ·在插入第i个记录时,前面的记录已经是有序的了

    ·可以用二分法查找第i个记录的正确位置

    由于直接插入排序算法利用了有序表的插入操作,故将顺序查找替换为二分法查找即可

    【特点】稳定

    空间代价:O(1)  时间代价:O(n^2)

     1 void BinaryInsertSort(int R[],int n)
     2 {
     3     for(int i = 1; i < n; i ++)  //共进行n-1次插入
     4     {
     5         int left = 0,right = i - 1;
     6         int temp = R[i];
     7         while(left <= right)
     8         {
     9             int middle = left + (right - left)/2;  //取中点
    10             if(temp < R[middle]) //取左区间
    11                 right = middle - 1;
    12             else    //取右区间
    13                 left = middle + 1;
    14         }
    15         //此时left处应为要插入的位置
    16         for(int j = i - 1; j >= left; j --)
    17             R[j + 1] = R[j];    //元素后移空出插入位
    18         R[left] = temp;
    19     }
    20 }

    3.希尔排序

    【思想】

    ·先将序列转化为若干小序列,在这些小序列内进行插入排序

    ·逐渐扩大小序列的规模,而减少小序列的个数,使得待排序序列逐渐处于更有序的状态

    ·最后对整个序列进行扫尾直接插入排序,从而完成排序

    【特点】不稳定

    空间代价:O(1)  时间代价:在O(logn)~O(n^2)之间,大致O(n^1.3)

     1 template <class T >
     2 void ShellSort (T Vector[], int arrSize)
     3 {
     4     T temp;
     5     int gap = arrSize / 2;  //gap是子序列间隔
     6     while (gap != 0) //循环,直到gap为零
     7     {
     8         for (int i = gap; i < arrSize; i ++)
     9         {
    10             temp = Vector[i];//直接插入排序
    11             int j = i;
    12             for ( ; j >= gap; j -= gap)
    13             {
    14                 if (temp < Vector[j-gap])
    15                     Vector[j] = Vector[j-gap];
    16                 else break;
    17             }
    18             Vector[j] = temp;
    19         }
    20         gap = gap / 2;//步长每次缩短为原来的一半
    21     }
    22 }
  • 相关阅读:
    开发两年!JVM方法调用都玩不明白,你离被炒鱿鱼不远了!
    springboot基本框架搭建零基础教程,对新手极为友好!
    SpingBoot整合Mybatis,这些小技巧你得知道,对你工作有很大的帮助!
    今天我们基于jdk8聊聊JVM-常量池,希望对大家有帮助!
    剑指 Offer 12. 矩阵中的路径
    WUSTCTF2020 funnyre
    2020 DJBCTF RE wp
    黑马c++基础的一个通讯录系统
    elf文件结构解读以及plt节got节的理解
    ubuntu16.04上编译android的可执行文件并调用本地so库
  • 原文地址:https://www.cnblogs.com/lca1826/p/6484962.html
Copyright © 2020-2023  润新知