跳转到内容

堆排序 ​

堆排序(Heap Sort)是一种基于堆数据结构的比较排序算法。堆是一个近似完全二叉树的结构,并同时满足堆的性质:即子节点的键值或索引总是小于(或者大于)它的父节点。

算法原理 ​

堆排序的基本思想是:

  1. 将待排序序列构造成一个大顶堆(升序排列)或小顶堆(降序排列)
  2. 此时整个序列的最大值(大顶堆)或最小值(小顶堆)就是堆顶元素
  3. 将堆顶元素与末尾元素交换,此时末尾就是最大(或最小)元素
  4. 重新调整堆结构,使其满足堆性质
  5. 重复步骤3-4,直到整个序列有序

JavaScript 实现 ​

js
/**
 * 调整堆结构,使其满足大顶堆性质
 * @param {Array} array - 数组
 * @param {number} n - 堆大小
 * @param {number} i - 需要调整的节点索引
 */
function heapify(array, n, i) {
  let largest = i; // 初始化最大值为根节点
  const left = 2 * i + 1;  // 左子节点
  const right = 2 * i + 2; // 右子节点
  
  // 如果左子节点存在且大于根节点
  if (left < n && array[left] > array[largest]) {
    largest = left;
  }
  
  // 如果右子节点存在且大于当前最大值
  if (right < n && array[right] > array[largest]) {
    largest = right;
  }
  
  // 如果最大值不是根节点
  if (largest !== i) {
    // 交换
    [array[i], array[largest]] = [array[largest], array[i]];
    
    // 递归调整受影响的子树
    heapify(array, n, largest);
  }
}

/**
 * 堆排序实现
 * @param {Array} array - 待排序的数组
 * @returns {Array} 排序后的新数组
 */
function heapSort(array) {
  // 创建数组副本以避免修改原数组
  const sorted = [...array];
  const n = sorted.length;
  
  // 构建大顶堆(从最后一个非叶子节点开始)
  for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
    heapify(sorted, n, i);
  }
  
  // 逐个从堆顶取出元素
  for (let i = n - 1; i > 0; i--) {
    // 将当前最大元素(堆顶)移到数组末尾
    [sorted[0], sorted[i]] = [sorted[i], sorted[0]];
    
    // 重新调整堆结构
    heapify(sorted, i, 0);
  }
  
  return sorted;
}

// 使用示例
const numbers = [64, 34, 25, 12, 22, 11, 90];
const sortedNumbers = heapSort(numbers);
console.log('原数组:', numbers);
console.log('排序后:', sortedNumbers);

算法特点 ​

  • 时间复杂度:
    • 最坏情况: O(n log n)
    • 最好情况: O(n log n)
    • 平均情况: O(n log n)
  • 空间复杂度: O(1) (原地排序)
  • 稳定性: 不稳定排序 (相等元素的相对位置可能会改变)
  • 适应性: 不是适应性排序算法

优缺点 ​

优点 ​

  1. 时间复杂度稳定,无论什么情况都是O(n log n)
  2. 是原地排序算法,空间复杂度为O(1)
  3. 不受输入数据分布影响,性能可预测
  4. 对大规模数据表现良好

缺点 ​

  1. 不是稳定排序算法
  2. 常数因子较大,实际运行时间可能比快速排序慢
  3. 对缓存不友好,局部性较差
  4. 实现相对复杂

应用场景 ​

  1. 大规模数据排序
  2. 对时间复杂度有稳定要求的场景
  3. 内存使用受限的场景(原地排序)
  4. 优先队列的实现

堆排序是一种高效的排序算法,尤其适用于大规模数据的排序,其时间复杂度在任何情况下都稳定为O(n log n)。