排序算法(2)——Shell排序简介及实现
其实希尔排序的适用特点可以总结如下:
1,分段特点明显。
2,具有局部有序性。
3,采用奇数步长,在很多情况下会有好的时间耗散。他一般的时间复杂对是O(n^1.25~1.6*n^1.25)或者也可记为O(n^1.5),空间复杂度为O(n)即无需额外空间。
4,可以对海量数据进行排序,前提是还来数据可以划分为许多子序列。他的时间复杂度正常情况下会好于插入排序。
shell排序是对插入排序的一个改装,它每次排序把序列的元素按照某个增量分成几个子序列,对这几个子序列进行插入排序,然后不断的缩小增量扩大每个子 序列的元素数量,直到增量为一的时候子序列就和原先的待排列序列一样了,此时只需要做少量的比较和移动就可以完成对序列的排序了
希尔排序是一种按照增量排序的方法。其中增量值是小于n的正整数。
shell排序的基本思想是:
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然 后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记 录放在同一组中进行直接插入排序为止。
可以根据百度百科中提供的图来直观的看一下:

(1)初始增量为3,该数组分为三组分别进行排序。(初始增量值原则上可以任意设置(0<gap<n),没有限制)
(2)将增量改为2,该数组分为2组分别进行排序。
(3)将增量改为1,该数组整体进行排序。
下面是我实现的简单算法记录:
#include <iostream>
#include <stdio.h>
using namespace std;
template <class T>
void ShellSort(T *a,int len){
int temp;
for (int inc=len/2;inc>0;inc/=2) //将待排序序列进行对半分组
{
for (int i=inc;i<len;i+=inc) //以增量inc进行跳跃遍历序列,为下面插入排序做准备
{
temp=a[i]; //保存当前遍历到的数据,为交换数据写入做准备
int j;
for (j=i;j>=inc;j-=inc) //当前数据要不断与它前面的所有数据做比较,so做循环,向前
{
if (a[j-inc]>temp) //将前面的数据与temp数据比较,大的就前面的数据j【j-inc】写入后面的位置
{
a[j]=a[j-inc];
}
else
break; //不符合条件的,将j指针继续前移
}
a[j]=temp; //找到j的合适位置,放入当前数据temp
}
}
}
int main(){
int arr[11]={21,13,3,56,51,21,64,58,72,102,33};
cout<<"Before Sorted,arry is: "<<endl;
for (int i=0;i<11;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
ShellSort(arr,11);
cout<<"After Sorted,arry is: "<<endl;
for (int i=0;i<11;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
system("pause");
return 0;
}

浙公网安备 33010602011771号