排序——插入排序

来源:互联网 发布:监控系统怎么连接网络 编辑:程序博客网 时间:2024/04/30 12:02

插入排序

这里总结一下三种插入排序的算法:

  • 直接插入排序
  • 折半插入排序
  • 希尔排序

直接插入排序

直接插入排序是一种最简单的排序方法,它的基本操作就是将一个记录插入到已排好序的有序表中,从而得到一个新的、记录数增1的有序表。

为了在查找插入位置的过程中避免数组下标出界,在r[0]处设置监视哨。

举例:

有一序列为:i=1: (5) 4 6 8 7 2 3i=2: (4 5) 6 8 7 2 3i=3: (4 5 6) 8 7 2 3i=4: (4 5 6 8) 7 2 3i=5: (4 5 6 7 8) 2 3i=6: (2 4 5 6 7 8) 3i=7: (2 3 4 5 6 7 8)

实现代码如下:

/*    InsertSort Implementation    Author:zzj    Date:17-6-17*/#include<cstdio>using namespace std;const int maxn = 100;int a[maxn];int n;void InsertSort(int *a){    int i,j;    for(i=2; i<=n; i++)    {        if(a[i] < a[i-1])     //需要将a[i]插入有序子表中         {            a[0] = a[i];      //复制为哨兵             a[i] = a[i-1];            for(j=i-2; a[0] < a[j]; j--)                a[j+1] = a[j];//记录后移             a[j+1] = a[0];    //插入到正确位置         }    }} int main(){    scanf("%d", &n);    int i,j;    for(i=1; i<=n; i++){        scanf("%d", &a[i]);    }       InsertSort(a);    for(int i=1; i<=n; i++)    {        printf("%d ", a[i]);    }    return 0;}

折半插入排序

这里再提供一种减小了比较次数的插入排序算法——折半插入排序,正是利用了插入到有序子表这一特点,有序就可以用二分。
就是找到要插入的位置是通过二分法来查找,这样会减少次数。

/*    BInsertSort Implementation    Author:zzj    Date:17-6-17*/#include<cstdio>using namespace std;const int maxn = 100;int a[maxn];int n; void BInsertSort(int *a){    int low, high, m;    for(int i=2; i<=n; i++)    {        a[0] = a[i];         //将a[i]暂存到a[0]         low = 1, high = i-1;             while(low <= high)   //在a[low..high]中折半查找有序插入的位置         {            m = (low + high)/2;            if(a[0] < a[m]) high = m-1;            else low = m+1;        }        for(int j=i-1; j>=high+1; j--) a[j+1] = a[j];//记录后移         a[high+1] = a[0];                            //插入     }}int main(){    scanf("%d", &n);    int i,j;    for(i=1; i<=n; i++){        scanf("%d", &a[i]);    }       BInsertSort(a);    for(int i=1; i<=n; i++)    {        printf("%d ", a[i]);    }    return 0;}

希尔排序

最后再介绍一下这个排序方法。
基本思想是:先将整个待排记录序列分割成若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。

举例:

有一序列为:初始态: 5 4 6 8 7 2 3  增量先是5第一趟: 2 3 6 8 7 5 4  增量变为3 第二趟: 2 3 5 4 7 6 8  增量变为1第三趟: 2 3 4 5 6 7 8  
/*    ShellSort Implementation    Author:zzj    Date:17-6-17*/#include<cstdio>using namespace std;const int maxn = 100;int a[maxn];int n; /*    希尔插入排序与直接插入相比,修改了:    1.前后记录位置的增量为dk,而不是1    2.a[0]只是暂存单元,不是哨兵 */void ShellInsert(int *a, int dk){    int i,j;    for(i=dk+1; i<=n; i++)    {        if(a[i] < a[i-dk])  //需将a[i]插入到有序增量子表         {            a[0] = a[i];    //暂存在a[0]             for(j=i-dk; j>0 && a[0] < a[j]; j-=dk)                a[j+dk] = a[j];//记录后移,查找插入位置             a[j+dk] = a[0];    //插入         }    }}/*希尔排序*/void ShellSort(int *a, int *dlta, int t){    for(int i=0; i<t; i++)    {        ShellInsert(a, dlta[i]);//增量逐渐递减为1    }}int main(){    scanf("%d", &n);    int i,j;    for(i=1; i<=n; i++){        scanf("%d", &a[i]);    }       int dt[3] = {5, 3, 1};    ShellSort(a, dt, 3);    for(int i=1; i<=n; i++)    {        printf("%d ", a[i]);    }    return 0;} 
原创粉丝点击