js实现堆排序的一种方法

225 阅读1分钟

第一步: 把无序数组构建成二叉堆(最大堆或最小堆)

第二步:循环删除堆顶元素,并将该元素移到集合尾部,调整堆产生新的堆顶

时间复杂度:O(nlongn) 空间复杂度:O(1)

function heapSort(arr) {
  // 把无序数组构建成最大堆
  for (let i = (arr.length - 2) / 2; i >= 0; i--) {
    downAdjust(arr, i, arr.length);
  }
  // 循环删除堆顶元素,移到末尾,调整产生新的堆顶
  for (let i = arr.length - 1; i > 0; i--) {
    [arr[i], arr[0]] = [arr[0], arr[i]];
    downAdjust(arr, 0, i);
  }
}

/**
 *
 * @param {待调整的堆} arr
 * @param {要下沉的父节点} parentIndex
 * @param {堆的有效大小} length
 */
function downAdjust(arr, parentIndex, length) {
  // temp保存父节点值,用户最后的赋值
  let temp = arr[parentIndex];
  let childIndex = 2 * parentIndex + 1;
  while (childIndex < length) {
    // 如果有右孩子,且右孩子大于左孩子的值,则定位到右孩子
    if (childIndex + 1 < length && arr[childIndex + 1] > arr[childIndex]) {
      childIndex++;
    }
    // 如果父节点大于任何一个孩子的值,则直接跳出
    if (temp >= arr[childIndex]) {
      break;
    }
    // 无须真正交换,单向赋值即可
    arr[parentIndex] = arr[childIndex];
    parentIndex = childIndex;
    childIndex = 2 * childIndex + 1;
  }
  arr[parentIndex] = temp;
}