一、前言
数据结构与算法,顺便刷leetcode,无意间发现了一个 我觉得讲解的比较好的网页,并且会拿leetcode里面的题目当做例题,如有需要,奉上网址:五分钟学算法
二、算法的来源
希尔算法是简单插入排序的改进版,实现简单,在中规模数据上表现的还不错,也称缩小增量排序。
三、算法的实现步骤
- 对元素进行分组,首先初始增量gap=length/2,将所有元素氛围gap组,每组两个元素,然后对每组里面的元素进行插入排序。
- 递减增量gap=gap/2,缩小增量使得每组里面的元素变多,再次对每组元素进行插入排序。
- 重复步骤2,使得增量逐步减少,直到增量为1,则所有元素排序完成。
四、图示(图片来源于网络:希尔排序)
五、代码
#include <iostream>
using namespace std;
void ShellSort(int* dps,int n)
{
for(int gap=n/2;;gap>0;gap/=2)//增量递减
for(int i=gap;i<n;i++)//对每组序列进行排序
{
int j;
int tmp=dps[i];
for(j=i-gap;j>0;j-=gap)//从每组序列的第二个元素开始插入
{
if(dps[j]>tmp)
dps[j+gap]=dps[j];
else
break;
}
if(tmp!=dps[i])
dps[j+gap]=tmp;
}
int main()
{
int num;
cout<<"请输入序列中元素的个数"<<endl;
cin>>num;
int dp[num];
for(int i=0;i<num;i++)
cin>>dp[i];
ShellSort(dp,num);
for(int i=0;i<num;i++)
cout<<dp[i]<<" ";
return 0;
}
六、算法性质
- 稳定性:可能导致相同元素的相对位置发生改变,故该排序算法不稳定。
- 空间复杂度:整个排序过程是在原数据上进行操作,故为 O(1);
- 时间复杂度:希尔排序的时间复杂度与增量序列的选取有关,本文选择的增量序列{n/2,(n/2)/2…1}(希尔增量),其最坏的时间复杂度为O(n2);一些经过优化的增量序列如Hibbard,其时间复杂度为O(n3/2);