记录学习--算法 第四天

139 阅读1分钟

没错又是我.我又来水文章来了,我又学到了两种排序.特地来记录一下

1.堆排序

堆排序(英语:Heapsort)是指利用[堆]这种数据结构所设计的一种排序算法。堆是一个近完全二叉的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

动图:

1.gif

代码:

 let heapSort = (function () {
    function heap(arr, length) {
      //进行大堆调整(从右到左,从下到上)
      let i = (length / 2 | 0) - 1 //计算出进行大堆调整的起点序号

      //进行循环调整
      while (i >= 0) {
        //找出左右子节点的序号
        let leftIndex = i * 2 + 1,
          rightIndex = i * 2 + 2

        //找出三个中最大值
        let max = arr[i],
          maxIndex = i

        //先和左比较
        if (arr[leftIndex] > max) {
          max = arr[leftIndex]
          maxIndex = leftIndex
        }

        //在和右比较
        if (rightIndex < length && arr[rightIndex] > max) {
          // max = arr[rightIndex] //赋值可以省略
          maxIndex = rightIndex
        }

        //交换
        maxIndex !== i && swap(arr, i, maxIndex)

        i--
      }

      //堆顶和堆尾交换
      swap(arr, 0, length - 1)
    }

    function swap(arr, a, b) {
      let tmp = arr[a]
      arr[a] = arr[b]
      arr[b] = tmp
    }

    return function (arr) {
      let len = arr.length
      //循环进行大堆调整
      for (let i = 0; i < len; i++) {
        heap(arr, len - i)
      }
    }
  })();


2.计数排序

计数排序是一种基本用不到的算法。他的时间复杂度为O(n)。快于任何排序算法的复杂度。但他的限制也是特别大的。就比如排序的数组不能是负数,不能是小数等等

动图:

1.gif 代码:

 function countSort(arr) {
    //计数
    let count = []
    for (let i = 0; i < arr.length; i++) {
      if (count[arr[i]]) {
        count[arr[i]]++
      } else {
        count[arr[i]] = 1
      }
    }
    //取出
    let index = 0
    for (let j = 0; j < count.length; j++) {
      let num = count[j]
      while (num > 0) {
        num--
        arr[index++] = j
      }
    }
  }