您的位置:首页 > 运维架构 > Shell

排序算法之希尔排序(Shellsort)

2016-05-16 09:18 633 查看
本文是自己在阅读《数据结构与算法分析c++描述》一书中的笔记、总结系列之一,主要会介绍排序算法中的谢尔排序的算法思想,代码实现。

谢尔排序之算法思想

谢尔排序使用一个序列hth_t,ht−1h_{t-1},…h2h_2,h1h_1来作为间隔排序,理论上只要h1h_1=1的任意递减序列都可以。但推荐两种序列:

第一种:谢尔增量 hth_t=⌊N2⌋\biggl\lfloor\frac N2\biggr\rfloor,t=hk+1h_{k+1}/2,hkh_k=⌊t2⌋\biggl\lfloor\frac t2\biggr\rfloor

第二种:Hibbard增量ht≈N2h_t \approx\frac N2, hk=2k−1h_k=2^k-1

使用谢尔增量时谢尔排序的最坏运行情形时间是Θ(N2)\Theta(N^2)。

使用Hibbard增量的谢尔排序的最坏情形的运行时间为Θ(N32)\Theta(N^\frac 32)。

当然还有许多其他已经提出的增量序列,其效果比Hibbard增量效果更好,这可以查阅文献来了解。本文以最为流行的(但效果不是很好)谢尔增量为例举一个实际的例子,并给出其代码实现。

example:example:



N=12,所以hth_t=⌊N2⌋=⌊122⌋=5\biggl\lfloor\frac N2 \biggr\rfloor=\biggl\lfloor\frac {12}2 \biggr\rfloor=5

首先进行6排序:



hk=⌊ht2⌋=62=3h_k=\biggl\lfloor\frac {h_t}2\biggr\rfloor=\frac 62=3

进行3排序:



最后进行1排序:


1排序的实质是插入排序,但由于经过6排序和3排序,此时的无序数列已经有一定的顺序,所以插入排序会进行较少的交换逆序即可。

谢尔排序之代码实现

#include <iostream>
#include <vector>
#include <math.h>
using namespace std;

void shellsort(vector<int> &arrayinput)
{
int N = arrayinput.size();
int h_t = floor(N / 2);
while (h_t >= 1)
{
for (int i = 0; i < arrayinput.size(); i++)
{
for (int j = 1; i + j*h_t < arrayinput.size(); j++)
{
int k;
int tmp = arrayinput[i + j*h_t];
for (k = j; k > 0 && tmp < arrayinput[i + (k-1)*h_t]; k--)
arrayinput[i + k*h_t] = arrayinput[i + (k-1)*h_t];
arrayinput[i + k*h_t] = tmp;
}

}
h_t = floor(h_t / 2) ;
}

}
void main()
{
int a;
vector<int> arrayinput;
cout << "please input :";
while (cin >> a)
arrayinput.push_back(a);
shellsort(arrayinput);
for(auto b : arrayinput)
cout << b << " ";
getchar();

}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: