希尔排序

来源:互联网 发布:开票软件默认密码 编辑:程序博客网 时间:2024/06/17 20:43

直接插入排序:
基本思想是,当插入第i个记录时,前面的R[1],…,R[i-1]已经排好序,这时,用R[i]的关键字依次与R[i-],…,R[1]比较,直到找到插入位置,假设为j;然后将第i-1个至第j个记录依次后移,最后将R[i]插入到位置j。

//代码实现for (int i=2; i<=n; i++)    {        int t=a[i];        int j=i-1;        while (j>0&&t<a[j])        {            a[j+1]=a[j];            j--;        }        a[j+1]=t;    }

希尔排序:
基本思想是,先将整个待排序记录序列分割成若干子序列,分别进行直接插入排序,待整个序列中的基本有序,再对全体记录进行一次直接插入排序。
子序列的构成不是简单地“ 逐段分割”,而是将相隔某个增量d的记录组成一个子序列,让增量di逐趟缩短,直到di=1位置。
d可以取di+1=di/2或者di+1=di/3;一般认为,di取奇数,且相互之间为素数。

#include <stdio.h>#include <algorithm>#include <iostream>#include <string.h>using namespace std;const int N=1e4;int a[N];int n;void shell(){    for (int d=n/2; d>0; d/=2 )     //d为每次排序的增量    {        for (int i=d+1; i<=n; i++)      //        {            int t=a[i];     //将待排序的数据存入t            int j=i-d;      //j是与a[i]间隔d的数据            while (j>0&&a[j]>t)     //a[j]与a[i]进行比较,因为j之前的已经排好序,所以不需要再进行比较            {                a[j+d]=a[j];        //a[j]向后挪d个位置                j-=d;            }            a[j+d]=t;        }    }}int main(){    scanf("%d",&n);    for (int i=1; i<=n; i++)        scanf("%d",a+i);    shell();    for (int i=1; i<=n; i++)    {        printf("%3d",a[i]);    }    return 0;}