• 数据结构躬行记4_插入排序算法(插入排序&折半插入排序&希尔排序)


    插入排序

    概念

    插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

    这里我们采用顺序表的存储方式来存储数据

    具体实现步骤

    1. 将待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列;
    2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;
    3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
    4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
    5. 将新元素插入到该位置后;
    6. 重复步骤2~5。

    代码实现

    #include<iostream>
    using namespace std;
    #define MAXSIZE  50
    typedef int keyType;
    typedef string other;
    typedef struct
    {
        keyType key;
        other  data;  //其他数据
    }arrayType;
    
    typedef struct{
    
       arrayType r[MAXSIZE+1];    //  r[0]闲置或者作为哨兵而存在
       int length;
    }SqList;
    
    
    void Sort(SqList &p)
    {   int j;
        for(int i=2;i<=p.length;i++)
        {
            if(p.r[i].key<p.r[i-1].key)
            {
                p.r[0].key=p.r[i].key;
                p.r[i].key = p.r[i-1].key;
                for(j = i-2;p.r[0].key<p.r[j].key;j--)
                {
                    p.r[j+1].key = p.r[j].key;
                }
                p.r[j+1].key = p.r[0].key;
            }
        }
    }
    int main()
    {
        int n,i;
        SqList arry;
       cout<<"请输入需要排序的个数:"<<endl;
       cin>>n;arry.length=n;
       cout<<"请依次输入这"<<n<<"个数:"<<endl;
       for(i=0;i<n;i++)
       {
           cin>>arry.r[i+1].key;
       }
    
    
       Sort(arry);
    
    
       cout<<"排序后:"<<endl;
       for(i=1;i<=n;i++)
       {
           cout<<arry.r[i].key<<" ";
       }
      return 0;
    }
    插入排序

    折半插入排序

    概念

    折半插入排序(Binary Insertion Sort)是对插入排序算法的一种改进,所谓排序算法过程,就是不断的依次将元素插入前面已排好序的序列中。

    排序思想

    遍历无序区间的所有元素,每次取无序区间的第一个元素Array[i],因为0~i-1是有序排列的,所以用中点m将其平分为两部分,然后将待排序数据同中间位置为m的数据进行比较,若待排序数据较大,则low~m-1分区的数据都比待排序数据小,反之,若待排序数据较小,则m+1~high分区的数据都比 待排序数据大,此时将low或high重新定义为新的合适分区的边界,对新的小分区重复上面操作。直到low和high 的前后顺序改变,此时high+1所处位置为待排序数据的合适位置。

    代码实现

    #include<iostream>
    using namespace std;
    #define MAXSIZE  50
    typedef int keyType;
    typedef string other;
    typedef struct
    {
        keyType key;
        other  data;  //其他数据
    }arrayType;
    
    typedef struct{
    
       arrayType r[MAXSIZE+1];    //  r[0]闲置或者作为哨兵而存在
       int length;
    }SqList;
    
    
    void Sort(SqList &p)
    {
        for(int i=2;i<=p.length;i++)
        {
            p.r[0].key=p.r[i].key;
            int low =1,high = i-1,m;
            if(p.r[i-1].key>p.r[i].key)
            {
                while(low<=high)
                {
                    m =(low+high)/2;
                    if(p.r[m].key<p.r[0].key)
                        low = m+1;
                    else
                        high = m-1;
                }
                for(int j=i-1;j>high;j--)
                    p.r[j+1].key = p.r[j].key;
                p.r[high+1]=p.r[0];
            }
        }
    }
    int main()
    {
        int n,i;
        SqList arry;
       cout<<"请输入需要排序的个数:"<<endl;
       cin>>n;arry.length=n;
       cout<<"请依次输入这"<<n<<"个数:"<<endl;
       for(i=0;i<n;i++)
       {
           cin>>arry.r[i+1].key;
       }
    
    
       Sort(arry);
    
    
       cout<<"排序后:"<<endl;
       for(i=1;i<=n;i++)
       {
           cout<<arry.r[i].key<<" ";
       }
      return 0;
    }

    希尔排序

    概念

    希尔排序又叫做缩小增量排序,其本质还是插入排序,只是在将待排序序列按照某种规则分成几个子序列,分别对这几个子序列进行直接插入排序,

    排序思想

    首先它把较大的数据集合分割成若干个小组(逻辑上分组),然后对每一个小组分别进行插入排序,此时,插入排序所作用的数据量比较小(每一个小组),插入的效率比较高

    代码实现

     1 #include<iostream>
     2 using namespace std;
     3 #define MAXSIZE  50
     4 typedef int keyType;
     5 typedef string other;
     6 typedef struct
     7 {
     8     keyType key;
     9     other  data;  //其他数据
    10 }arrayType;
    11 
    12 typedef struct{
    13 
    14    arrayType r[MAXSIZE+1];    //  r[0]闲置或者作为哨兵而存在
    15    int length;
    16 }SqList;
    17 
    18 void ShellInsert(SqList &p,int dk)
    19 {
    20     for(int i=dk+1;i<=p.length;i++)
    21     {
    22         if(p.r[i].key<p.r[i-dk].key)
    23         {
    24             p.r[0] = p.r[i];
    25             p.r[i]=p.r[i-dk];
    26             p.r[i-dk]=p.r[0];
    27         }
    28     }
    29 }
    30 
    31 void ShellSort(SqList &p,int dt[],int t)
    32 {
    33     for(int k=0;k<t;k++)
    34     {
    35        ShellInsert(p,dt[k]);
    36     }
    37 }
    38 int main()
    39 {
    40      int n,i;
    41     SqList arry;
    42    cout<<"请输入需要排序的个数:"<<endl;
    43    cin>>n;arry.length=n;
    44    cout<<"请依次输入这"<<n<<"个数:"<<endl;
    45    for(i=0;i<n;i++)
    46    {
    47        cin>>arry.r[i+1].key;
    48    }
    49  //增量序列
    50     int dt[3] = {5,3,1};
    51     ShellSort(arry,dt,3);
    52 
    53 
    54    cout<<"排序后:"<<endl;
    55    for(i=1;i<=n;i++)
    56    {
    57        cout<<arry.r[i].key<<" ";
    58    }
    59 
    60   return 0;
    61 }

    插入总结

    1. 希尔排序不可以用于链式结构
    2. 空间复杂度都是O(1)
    3. 时间复杂度:O(n2),O(n2),n(log2n)2
    4. 插入排序适用于:小规模数据数据或者基本有序
      时十分高效。

  • 相关阅读:
    typescript-泛型-类型检查
    typescript-class-interface
    typescript-类class
    typescript-接口interface
    Oracle 密码过期
    VMware Redhat虚拟机扩容硬盘
    华硕 U系列电脑拆后盖注意事项
    VS + QT 出现 LNK2001 无法解析的外部符号 QMetaObject 的问题
    c++ _pFirstBlock == pHead
    c++ 套路多
  • 原文地址:https://www.cnblogs.com/g414056667/p/13662927.html
Copyright © 2020-2023  润新知