今天在学习希尔排序的时候,发现网上有很多希尔排序的算法,大同小异,但是看了一个小时没看懂,于是决定先百度一下希尔排序的原理再看网上的算法,等查阅了希尔排序的原理后,我发现网上很多教程里的希尔排序算法并不是很契合希尔排序的思想,于是自己写了一下希尔排序的算法。
这里的增量序列选择了len/2,len/2/2...,直到为1,因为这是希尔建议的增量序列
希尔排序原理:希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
看到这个原理,我第一反应就是递归啊,代码如下:
var arr = [5,9,3,7,10,78,56,4,6,24];
var len = arr.length;
shellSort(Math.floor(len/2));
function shellSort (step) {
for (i = 0; i < step; i++) {
for (j = i+step; j < len; j += step) {
var cur = arr[j];
var k = j-step;
while (k>-1){
if (arr[k]>cur) {
arr[k+step] = arr[k];
k= k-step;
} else{
break;
}
}
arr[k+step] = cur;
}
}
if (step>1) {
shellSort(Math.floor(step/2))
}
}
console.log(arr);
第一趟排序:
step = 5,分为5组,如下,
[5,78]
[9,56]
[3,4]
[7,6]
[10,24]
五组分别排序后
[5,78]
[9,56]
[3,4]
[6,7],只有这一组变化了
[10,24]
即第一趟排序后数组为[5,9,3,6,10,78,56,4,7,24]
第二趟排序
step = 2,分为两组
[5,3,10,56,7]
[9,6,78,4,24]
分别排序后
[3,5,7,10,56]
[4,6,9,24,78]
即第二趟排序后[3,4,5,6,7,9,10,24,56,78],这个例子很巧合的在第二趟排序后就已经是正序了,这也说明希尔排序的话,最后step=1时(即进行直接插入排序时),只需要进行很少的移动和插入,甚至在本例中不需要再进行移动和插入
第三趟排序
step = 1,分为一组,即对第二趟排序的结果进行直接插入排序
结果为[3,4,5,6,7,9,10,24,56,78]