算法——希尔排序(ShellSort)

希尔排序,又称缩小增量排序,也是一种插入排序方法。它与插入排序的不同之处在于,它会优先比较距离较远的元素。

希尔排序的核心在于间隔序列的设定。既可以提前设定好间隔序列,也可以动态地定义间隔序列。

希尔排序的基本思想是,将整个待排序记录序列分割成若干个子序列,然后对每一个子序列进行直接插入排序。具体如下:

(1)先取一个正整数分成d1,把全部记录d1个组,所有距离为d1的倍数的记录看成一组,然后在各组内进行插入排序

(2)然后去d2(d2<d1)

(3)重复上述分组和排序操作,知道di=1(i>=1)位置,即所有记录称为一个组,最后对这个组进行插入排序。一般选d1约为n/2,d2为d1/2,d3为d2/2,...,di=1

实现代码:

function shellSort(arr){
	if(arr.length<2){return arr;}
	var gap=Math.floor(arr.length/2);
	var tmp;
	while(gap>0){
		for(var i=gap;i<arr.length;i++){
			tmp=arr[i];
			for(var j=i-gap;j>=0;j-=gap){
				if(arr[j]>tmp){
					arr[j+gap]=arr[j];
				}else{
					break;
				}
			}
			arr[j+gap]=tmp;
			console.log(arr);
		}
		gap=Math.floor(gap/2);
	}
	return arr;
}

结果测试:


由上可以看到,对于长度为9的数组,其间隔gap取值依次为4,2,1.


关于动态定义间隔序列,以下摘自搜索的一段实现代码,为了测试使用的gap取值,稍微修改了一下console.log()的打印内容:

function shellSort(arr) {
    var len = arr.length,
        temp,
        gap = 1;
    //console.time('希尔排序耗时:');
    while(gap < len/5) {          //动态定义间隔序列
        gap =gap*5+1;
    }
	console.log(gap);
    for (gap; gap > 0; gap = Math.floor(gap/5)) {
	console.log(gap);
        for (var i = gap; i < len; i++) {
            temp = arr[i];
            for (var j = i-gap; j >= 0 && arr[j] > temp; j-=gap) {
                arr[j+gap] = arr[j];
            }
            arr[j+gap] = temp;
        }
    }
    console.timeEnd('希尔排序耗时:');
    return arr;
}

根据上面代码,在Chrome的打印台测试:


可以看到gap的取值依次是6,1,只进行了两次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值