算法——希尔排序(ShellSort)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012194956/article/details/79451585

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

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

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

(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,只进行了两次。

猜你喜欢

转载自blog.csdn.net/u012194956/article/details/79451585