希尔排序

1.什么叫希尔排序

希尔排序(Shell Sort)是插入排序的一种。是针对直接插入排序算法的改进。该方法又称缩小增量排序,因DL.Shell于1959年提出而得名

2.希尔排序的基本思想

先取一个小于n的整数d1作为第一个增量,把传进来的数据记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量(1<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

3.举例

 输入数据为   n=8 
        即a[8]={48 26 22 68 46 42 36 84 66}

输出数据:
        a[8]={22 26 36 42 46 48 66 68 84}
过程:
     1.首先将原始数据  48 26 22 68 46 42 36 84 66以d1=8/2=4划分,
间隔为4的归为一个子序列,再对每一个子序列 用插入排序排好

          (48,46 66)——> 46 48 66
          (26,42   )——> 26 42
          (22,36   )——> 22 36 
          (68,84   )——> 68 84 
排序结果:46 26 22 68 48 42 36 84 66(从第一列到第二列到第三列)
    2.再将上述排序结果以d2=2划分
         (46 22 48 36 66)——> 22 36 46 48 66
         (26 68 42 84   )——> 26 42 68 84
排序结果:22 26 36 42 46 68 48 84 66(从第一列到第二列到第x列)
   3.再将上述排序结果按d3=1划分
            (22 26 36 42 46 68 48 84 66)——> 22 26 36 42 46 48 66 68 84
排序结果:22 26 36 42 46 48 66 68 84 */

4.C++代码示意

/*希尔排序主要思想:
1.先选定一个整数d1作为初始间隔,将此文件记录数按照d1从第一个开始分成若干个“子序列”,
 所有间隔为d1的记录为一个子序列,再各序列中用插入排序
2.选定d2<d1,以d2为间隔重复1的操作
3.直至间隔数di=1为止排好序
ps:取di的方法有很多,这里取d1=n/2,di=d(i-1)/2
*/
#include<iostream>
using namespace std;
int a[100];
//交换函数,目的是交换数组中两个元素的位置 
void swap(int a[],int i,int j)
{
	int temp;
    temp=a[i];
	a[i]=a[j];
	a[j]=temp;
	
}
//希尔排序
void Shell_Sort(int a[],int n) 
{ 
   int temp;
   for(int d=n/2;d>=1;d=(d/2)){//减小增量,直到增量为1 
   //对每一轮进行插入排序 
   	 for(int i=d;i<n;i++){ 
        if(a[i]<a[i-d]){
        	temp=a[i];
		  for(int j=i-d;j>=0&&a[j]>temp;j=j-d)
		  	   swap(a,j,j+d);
        }
    }  
  }
}
 
//主函数 
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	  cin>>a[i];
	Shell_Sort(a,n);

	for(int i=0;i<n;i++)
	{
		cout<<a[i]<<" ";
	} 
	cout<<endl;
	return 0;
} 
/*input:
        9
        48 26 22 68 46 42 36 84 66
  output:
        22 26 36 42 46 48 66 68 84
过程:
     1.首先将原始数据  48 26 22 68 46 42 36 84 66以d1=8/2=4划分,
	 间隔为4的归为一个子序列,再对每一个子序列 用插入排序排好序
(48,46 66)——> 46 48 66
(26,42   )——> 26 42
(22,36   )——> 22 36 
(68,84   )——> 68 84 
排序结果:46 26 22 68 48 42 36 84 66(从第一列到第二列到第三列)
2.再将上述排序结果以d2=2划分
(46 22 48 36 66)——> 22 36 46 48 66
(26 68 42 84   )——> 26 42 68 84
排序结果:22 26 36 42 46 68 48 84 66(从第一列到第二列到第x列)
3.再将上述排序结果按d3=1划分
 (22 26 36 42 46 68 48 84 66)——> 22 26 36 42 46 48 66 68 84
排序结果:22 26 36 42 46 48 66 68 84 */


5.算法分析

通过上述分析可知,希尔排序的关键不是随便分组后各自排序,而是将相隔某个“增量”的记录组成一个子序列,实现跳跃式的移动,使得排序的效率提高。

这里的“增量”选取非常关键,但是究竟选什么增量才是最好,目前还是一个数学难题,迄今为止还没有人找到一种最好的增量序列。不过研究表明,当增量序列为dlta[k]=2^(t-k+1)-1  (0<=k<=t<=log2(n+1))时,可以获得不错的效果,其时间复杂度为O(n^1.5),要好于直接排序的O(n^2)。需要注意的是,增量序列的最后一个增量值必须等于1才行。另外由于记录是跳跃式的移动,希尔排序并不是一个稳定的排序算法。

排序方法
平均情况
最好情况
最坏情况
辅助空间
稳定性
希尔排序O(nlogn)~O(n^2)O(n^1.3)O(n^2)
O(1)不稳定




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值