希尔排序(ShellSort)思想与实现

  希尔排序属于高级的排序方法,接下来阐述一下该排序算法的思想。

(1) 希尔排序的思想

  希尔排序的思想就是:定义一个呈递减变化的步长gap,假设数组长度为size,最开始定义的步长为gap=size/2,并从第0个元素开始,将数组中间隔为gap的元素构成子数组,共构成gap个子数组,之后对每个子数组进行排序(排序方法任意),此时第一步就算完成了;然后定义第二步的步长为gap=gap/2,并做与第一步相同的操作;以此类推,每次取步长为gap=gap/2,直到对gap为1的数组进行排序后,整个排序过程结束。

为了更好地理解该排序算法的思想,我们来看下面的图片:


从上图可以知道,原始数组为:10   8   6   20   4   3   22   1   0   15   16,以排升序为例,接下来进行分步操作。

  第一步:由于数组长度size=11,故gap=11/2=5,故共分为5个子数组,分别对这5个子数组进行排序后,数组变化为:3   8   1   0   4   10   22   6   20   15   16。

  第二步:由于第一步的gap为5,故该步骤的gap=5/2=2,但可以看到图片上的gap为3,这是由于图片作者失误导致的,在后面的算法实现中,本文作者不会出现类似的错误,读者大可放心。但这不影响我们来掌握希尔排序的思想,我们根据图片中的gap为3,故共分成3个子数组,分别对这3个子数组进行排序后,数组变化为:0   4   1   3   6   10   15   8   20   22   16。

  第三步:由于第二步的gap为3,故该步骤的gap=3/2=1,故共分为1个子数组,对这1个子数组进行排序后,数组变化为:0   1   3   4   6   8   10   15   16   20   22。

(2) 希尔排序的实现

  本次排序算法采用C++模版编程来实现,且对每个子数组采用冒泡排序进行排序。

#include <iostream>
#include <iterator>

using namespace std;

template<class T,size_t N>
void PrintArr(T (&arr)[N])
{
    copy(arr,arr+N,ostream_iterator<T>(cout,"  "));
    cout << endl;
}
template<class T,size_t N>
void ShellSort(T (&arr)[N])
{
    size_t gap(N);
    size_t end;
    size_t step;
    while(gap > 1) {
        step = 0;
        gap /= 2;
        do {
            size_t i(step);
            end = N;
            while(end > gap) {
                for(; i < end; i += gap) {
                    if(arr[i] > arr[i+gap] and (i+gap) < N) {
                        swap(arr[i],arr[i+gap]);
                        PrintArr(arr);
                    }
                }
                end -= gap;
                i = step;
            }
            step++;
        } while(step < gap);
    }
}

int main()
{
    int arr[] = {10,8,6,20,4,3,22,1,0,15,16};
//	int arr[] = {10,9,8,7,6,5,4,3,2,1};
//	int arr[] = {1,2,3,4,5,6,7,8,9,10};
    cout << "The init:" << endl;
    PrintArr(arr);
    cout << "The sort:" << endl;
    ShellSort(arr);
    cout << "The final:" << endl;
    PrintArr(arr);
}
原始数组为:10   8   6   20   4   3   22   1   0   15   16

程序运行结果为:0   1   3   4   6   8   10   15   16   20   22

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值