JS插入排序希尔算法思维__数据结构与算法

排序算法中传统插入排序算法没有分组的思想,直到希尔提出分组这种分而治之的思维能让一些算法得到改进,插入排序算法具体思路不再赘述,网上有大量教程思路,本贴主要谈论插入排序算法引入希尔算法思维后是如何改进的
  • 先创建随机数组
//生成随机数
  function GetRandomNum(Min, Max) {
    let Range = Max - Min;
    let Rand = Math.random();
    return (Min+Math.round(Rand * Range));
  }

  //生成随机数组
  let arr = []
  for (let i = 0; i < 10; i++) { //10个元素的随机数组
    arr.push(GetRandomNum(0, 100)) //随机数范围在0-100
  }
  console.log('原数组:' + arr);
  • 插入排序算法
//1.传统插入排序
  let len = arr.length
  function insertSort(arr){
    let insertValue //待插入元素
    ,insertIndex //待插入位置
    ,gap=1//步长,普通插入排序没有用希尔分组思维,待插入元素始终与前一个数依次比较,故步长为1,不理解可以先不管,就先把gap看成常量1
    for (let i = gap; i <len ; i++) {//以下先只看for循环第一次,后面循环以此类推
      insertValue=arr[i] //for循环第一次i=gap=1,第一个待插入元素是arr[1]
      insertIndex=i-gap //for循环第一次待插入位置是i-gap=0
      while (insertIndex>=0&&insertValue<arr[insertIndex]){ //设置边界,带插入位置要大于0 并且待插入元素与待插入位置上的元素相比较更小的时候才进入下面移位循环
        arr[insertIndex+gap]=arr[insertIndex] //待插入位置的元素整体右移
        insertIndex-=gap //要比较的位置-1左移方便下次循环
      }
      arr[insertIndex+gap]=insertValue //待插入元素最终找到了自己的位置
      //for循环第一次结束,执行i++后i变成2故下一次循环arr[2]元素成为待插入元素
    }
    return arr
  }
  insertSort(arr)
  console.log('插入排序后数组:' + arr)
  • 用希尔分组思维后的插入排序
//希尔插入排序
  function shellSort(arr) {
    let insertIndex , insertValue,gap = Math.floor(len / 2) //将数组整体分组,分而治之提高效率.这里数组长度10,除二分为5组,故设置步长gap为5
    //步长gap表示待插入元素位置与待比较元素位置的距离,以上数组10个数,分五组,每组两个元素相比较,元素arr[0]与arr[5]相比较,元素arr[1]与arr[6]相比较以此类推
    for (; gap > 0; gap = Math.floor(gap / 2)) { //步长要大于0,每次比较完后又再次除二分更多组,故步长也跟着变化.
      for (let i = gap; i < len; i++) {//以下代码与普通插入法完全一致
      //for循环第一次待插入元素位置为i=gap=5,arr[5]也就是数组第六个元素
        insertValue=arr[i]
        insertIndex=i-gap //for循环第一次待插入位置为i-gap=0,arr[0]待插入位置的元素也就是第一个元素
          while (insertIndex>=0&&insertValue<arr[insertIndex]){ //符合条件进入移位循环
          arr[insertIndex+gap]=arr[insertIndex]
          insertIndex-=gap
        }
          arr[insertIndex+gap]=insertValue //待插入元素最终找到自己的位置
      }
      //第一次循环结束,i++后i为6,故第二次循环待插入元素为arr[6]
    }
    return arr
  }
  shellSort(arr)
  console.log('插入排序后数组:' + arr)
  • 比较上面两段插入排序代码可看出,用了希尔的思路设计的插入排序代码仅仅只多了gap = Math.floor(gap / 2)这个gap步长关键点 和for (; gap > 0; gap = Math.floor(gap / 2)){}这个分组循环,可以看出传统插入排序因为没有分组思维所以没有进行分组操作,因为没有分组操作所以没有将gap这个步长作为重点提出.毕竟传统插入排序只需要与前一个数比较,步长为1,没太大必要关注这个步长.所以很多教程没有重点提出来说,但这个步长是实在存在不可完全忽略的,也是插入排序引用希尔的思路来改进的关键点!
  • 注意:希尔重要的是提出分而治之的算法思路,不仅仅用于插入排序算法!
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值