JavaScript希尔排序
Posted 橘猫吃不胖~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript希尔排序相关的知识,希望对你有一定的参考价值。
javascript希尔排序
1 思路
希尔排序是一种基于插入排序的快速排序算法,也成为缩小增量排序。简单插入排序对于大规模乱序数组很慢,因为元素只能一点一点地从数组的一端移动到另一端。希尔排序为了加快速度简单地改进了插入排序,同时该算法是冲破O(n2)的第一批算法之一。
希尔排序是把数组按照一定的增量分组,对每组使用直接插入排序算法排序;然后缩小增量继续分组排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个数组被分成一组,再次排序,就可以完成整个数组的排序。
增量的选择:
- 希尔建议的间距是N/2,每一趟排序分成两半,也就是说,对于N=100的数组,增量间隔序列为50,25,12,6,3,1。
- Hibbard增量序列,增量的算法为2k-1,也就是1、3、5、7…等,这种算法最坏复杂度为O(N3/2),猜想的平均复杂度是O(N5/4),目前尚未被证明。
- Sedgewick增量序列,1,5,19,41,109,…,该序列中的项是94i-92i+1,或者是4i-3*2i+1。这种增量最坏复杂度为O(N4/3),平均复杂度是O(N7/6),但是均未被证明。
示例:对数组 [5,2,3,1,4,3,2,1] 进行从小到大排序
增量 | 排序结果 |
---|---|
Math.floor(8/2)=4 | 第一组:5和4进行排序,5比4大,两数交换位置,排序后结果为 [4,2,3,1,5,3,2,1] |
第二组:2和3进行排序,2比3小,无需交换位置,排序后结果: [4,2,3,1,5,3,2,1] | |
第三组:3和2进行排序,3比2大,两数交换位置,排序后结果: [4,2,2,1,5,3,3,1] | |
第四组:1和1进行排序,两数相同,无需交换位置,排序后结果: [4,2,2,1,5,3,3,1] | |
4/2=2 | 第一组:[4,2,5,3]进行排序,排序后结果:[2,3,4,5],数组整体结果: [2,2,3,1,4,3,5,1] |
第二组: [2,1,3,1]进行排序,排序后结果:[1,1,2,3],数组整体结果: [2,1,3,1,4,2,5,3] | |
2/2=1 | 增量为1时,按照插入排序正常过程进行排序 |
2 代码实现
示例代码:从小到大排序
function shellSort(arr) // 参数为需要排序的数组
// 获取初始的增量
let gap = Math.floor(arr.length / 2);
while (gap >= 1) // 增量小于1时结束循环
// 从gap开始遍历,因为插入排序假设第一个是有序的
for (let i = gap; i < arr.length; i++)
let j = i; // 为插入排序从后向前排序提供条件
// 如果排序的后面的数字小于前面的,交换两个数的位置
while (arr[j] < arr[j - gap] && j - gap >= 0)
let temp = arr[j];
arr[j] = arr[j - gap];
arr[j - gap] = temp;
// j减小gap从后向前遍历
j -= gap;
// 增量每次都减小一半
gap = Math.floor(gap / 2);
return arr;
示例代码:从大到小排序
function shellSort(arr) // 参数为需要排序的数组
// 获取初始的增量
let gap = Math.floor(arr.length / 2);
while (gap >= 1) // 增量小于1时结束循环
// 从gap开始遍历,因为插入排序假设第一个是有序的
for (let i = gap; i < arr.length; i++)
let j = i; // 为插入排序从后向前排序提供条件
// 如果排序的后面的数字大于前面的,交换两个数的位置
while (arr[j] > arr[j - gap] && j - gap >= 0)
let temp = arr[j];
arr[j] = arr[j - gap];
arr[j - gap] = temp;
// j减小gap从后向前遍历
j -= gap;
// 增量每次都减小一半
gap = Math.floor(gap / 2);
return arr;
新人创作打卡挑战赛
发博客就能抽奖!定制产品红包拿不停!
以上是关于JavaScript希尔排序的主要内容,如果未能解决你的问题,请参考以下文章