堆排序

我们可以使用二叉堆数据结构来帮助我们创建一个非常著名的排序算法:堆排序算法。它包含下面三个步骤。

(1) 用数组创建一个最大堆用作源数据。

(2) 在创建最大堆后,最大的值会被存储在堆的第一个位置。我们要将它替换为堆的最后一个值,将堆的大小减1。

(3) 最后,我们将堆的根节点下移并重复步骤2直到堆的大小为1。

我们用最大堆得到一个升序排列的数组(从最小到最大)。如果我们想要这个数组按降序排列,可以用最小堆代替。

 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>堆排序</title>
</head>
<body>
  
</body>
<script>
  function buildMaxHeap(arr) {   // 建立大顶堆
    len = arr.length;
    for (var i = Math.floor(len/2); i >= 0; i--) {
        heapify(arr, i);
    }
  }
  function heapify(arr, i) {     // 堆调整
    var left = 2 * i + 1,
        right = 2 * i + 2,
        largest = i;
    if (left < len && arr[left] > arr[largest]) {
        largest = left;
    }
    if (right < len && arr[right] > arr[largest]) {
        largest = right;
    }
    if (largest != i) {
        swap(arr, i, largest);
        heapify(arr, largest);
    }
  }
  function swap(arr, i, j) {
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
   }
  function heapSort(arr) {
   debugger;
   //创建一个最大堆
   buildMaxHeap(arr);
   // 循环数据 交换堆首与最后一个 数组减去最后的一个(也就是最大堆) 重新调整堆
   for (var i = arr.length-1; i > 0; i--) {
        // 交换 将堆的第一个与最后一个交换
        // 0 是堆的第一个 i是堆的最后一个
        swap(arr, 0, i);
        //数组减掉一 减去最后一个
        len--;
        //交换堆
        heapify(arr, 0);
    }
    return arr;
  }
  let data  = heapSort([4,10,3,5,1])
  console.log(data);
</script>
</html>

 

将堆拆分为两个部分

function buildMaxHeap(arr) {   // 建立大顶堆
    len = arr.length;
    for (var i = Math.floor(len/2); i >= 0; i--) {
        heapify(arr, i);
    }
  }

 

交换数值

function swap(arr, i, j) {
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
   }

 

对堆进行调整

 

  function heapify(arr, i) {     // 堆调整
    var left = 2 * i + 1,
        right = 2 * i + 2,
        largest = i;
    if (left < len && arr[left] > arr[largest]) {
        largest = left;
    }
    if (right < len && arr[right] > arr[largest]) {
        largest = right;
    }
    if (largest != i) {
        swap(arr, i, largest);
        heapify(arr, largest);
    }
  }
输入数据:4,10,3,5,1
         4(0)
        / \
     10(1)3(2)
    / \
 5(3)1(4)

括号中的数字表示数组中的索引 
数据表示。

将堆化过程应用于索引1:
         4(0)
        / \
    10(1)3(2)
    / \
5(3)1(4)

将heapify过程应用于索引0:
        10(0)
        / \
     5(1)3(2)
    / \
 4(3)1(4)
heapify过程以递归方式调用自身以构建堆
 以自上而下的方式。

 

posted @ 2019-10-27 15:24  1点  阅读(168)  评论(0编辑  收藏  举报