数据结构躬行记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. 插入排序适用于:小规模数据数据或者基本有序
    时十分高效。

posted @ 2020-09-13 20:13  17_Xtreme  阅读(147)  评论(0编辑  收藏  举报