希尔排序C++实现

shell排序在不相邻的元素之间比较和交换。利用了插入排序的最佳时间代价特性,它试图将待排序序列变成基本有序的,然后再用插入排序来完成排序工作。

在执行每一次循环时,Shell排序把序列分为互不相连的子序列,并使各个子序列中的元素在整个数组中的间距相同,每个子序列用插入排序进行排序。

1.举例说明希尔排序法过程

以一个整数序列为例来说明{12,45,90,1,34,87,-3,822,23,-222,32},该组序列包含N=11个数。不少已有的说明中通常举例10个数,这里说明一下,排序算法与序列元素个数无关! 
首先声明一个参数:增量gap。gap初始值设置为N/2。缩小方式一般为gap=gap/2. 
第一步,gap=N/2=5,每间隔5个元素取一个数,组成一组,一共得到5组: 
这里写图片描述 
对每组使用插入排序算法,得到每组的有序数列: 
这里写图片描述 
至此,数列已变为: 
这里写图片描述

第二步,缩小gap,gap=gap/2=2,每间隔2取一个数,组成一组,共两组: 
这里写图片描述 
同理,分别使用插入排序法,得到每组的有序数列: 
这里写图片描述 
至此,数列已变为: 
这里写图片描述 
第三步,进一步缩小gap,gap=gap/2=1,此时只有一组,直接使用插入排序法,玩完成排序,图略。

2.shell排序C++代码实现

步进方式我这里用的是:gap=gap/3

#include<iostream>

using namespace std;
const int INCRGAP = 3;
void shellSort(int a[],int len)
{
    int insertNum = 0;
    unsigned gap = len/INCRGAP + 1; // 步长初始化,注意如果当len<INCRGAP时,gap为0,所以为了保证进入循环,gap至少为1!!!
    while(gap) // while gap>=1
    {
        for (unsigned i = gap; i < len; ++i) // 分组,在每个子序列中进行插入排序
        {
            insertNum = a[i];//将当前的元素值先存起来方便后面插入
            unsigned j = i;
            while (j >= gap && insertNum < a[j-gap])//寻找插入位置
            {
                a[j] = a[j - gap];
                j -= gap;
            }
            a[j] = insertNum;
        }
        gap = gap/INCRGAP;
    }
}
int main()
{
    int array[11] = {2, 1, 4, 3, 11, 6, 5, 7, 8, 10, 15};
    shellSort(array, 11);
    for(auto it: array)
    {
        cout<<it<<endl;
    }
    return 0;
}

注意:

如果步进方式为gap=gap/2的话不用考虑下面这个问题:

 

那么gap初始化的时候就不用+1了,代码如下:

#include<iostream>

using namespace std;
const int INCRGAP = 2;
void shellSort(int a[],int len)
{
    int insertNum = 0;
    unsigned gap = len/INCRGAP; // 步长初始化
    while(gap) // while gap>=1
    {
        for (unsigned i = gap; i < len; ++i) // 分组,在每个子序列中进行插入排序
        {
            insertNum = a[i];//将当前的元素值先存起来方便后面插入
            unsigned j = i;
            while (j >= gap && insertNum < a[j-gap])//寻找插入位置
            {
                a[j] = a[j - gap];
                j -= gap;
            }
            a[j] = insertNum;
        }
        gap = gap/INCRGAP;
    }
}
int main()
{
    int array[11] = {2, 1, 4, 3, 11, 6, 5, 7, 8, 10, 15};
    shellSort(array, 11);
    for(auto it: array)
    {
        cout<<it<<endl;
    }
    return 0;
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值