堆排序(Heap Sort)是一种利用堆数据结构设计的排序算法。它首先将数组构建成一个最大堆(父节点总是大于子节点),然后不断取出堆顶的最大元素,放到数组末尾,同时调整剩余元素重新形成堆,直到所有元素都被取出。

点击"开始排序"查看动画

算法步骤

  1. 将待排序数组构建成一个最大堆(Build Max-Heap)
  2. 此时堆顶元素(arr[0])为最大值
  3. 将堆顶元素与最后一个元素交换
  4. 堆大小减1,对新的堆顶执行下沉操作(Heapify)
  5. 重复步骤3-4,直到堆大小为1

时间与空间复杂度

情况 时间复杂度 说明
建堆 O(n) 自底向上建堆的时间复杂度
排序(所有情况) O(n log n) 每次取出堆顶需要O(log n)调整
空间复杂度 O(1) 原地排序,只需常数额外空间

堆排序是不稳定排序,相等元素的相对顺序可能改变。

适用场景

  • 需要原地排序且保证O(n log n)最坏情况性能
  • 实现优先队列数据结构
  • 找出数组中前K大/小的元素
  • 系统调度、任务优先级管理
优先队列 Top-K问题 任务调度 内存受限场景

代码实现

def heapify(arr, n, i):
    """维护最大堆性质"""
    largest = i
    left = 2 * i + 1
    right = 2 * i + 2
    
    # 左子节点更大
    if left < n and arr[left] > arr[largest]:
        largest = left
    
    # 右子节点更大
    if right < n and arr[right] > arr[largest]:
        largest = right
    
    # 如果最大值不是根节点,交换并继续调整
    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]
        heapify(arr, n, largest)


def heap_sort(arr):
    """堆排序算法"""
    n = len(arr)
    
    # 构建最大堆(从最后一个非叶节点开始)
    for i in range(n // 2 - 1, -1, -1):
        heapify(arr, n, i)
    
    # 逐个取出堆顶元素
    for i in range(n - 1, 0, -1):
        arr[0], arr[i] = arr[i], arr[0]  # 交换堆顶和末尾
        heapify(arr, i, 0)  # 重新调整堆
    
    return arr


# 使用示例
arr = [12, 11, 13, 5, 6, 7]
print(heap_sort(arr))
# 输出: [5, 6, 7, 11, 12, 13]
public class HeapSort {
    
    /**
     * 维护最大堆性质
     */
    private static void heapify(int[] arr, int n, int i) {
        int largest = i;
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        
        // 左子节点更大
        if (left < n && arr[left] > arr[largest]) {
            largest = left;
        }
        
        // 右子节点更大
        if (right < n && arr[right] > arr[largest]) {
            largest = right;
        }
        
        // 如果最大值不是根节点
        if (largest != i) {
            int temp = arr[i];
            arr[i] = arr[largest];
            arr[largest] = temp;
            
            heapify(arr, n, largest);
        }
    }
    
    /**
     * 堆排序算法
     */
    public static void heapSort(int[] arr) {
        int n = arr.length;
        
        // 构建最大堆
        for (int i = n / 2 - 1; i >= 0; i--) {
            heapify(arr, n, i);
        }
        
        // 逐个取出堆顶元素
        for (int i = n - 1; i > 0; i--) {
            int temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;
            
            heapify(arr, i, 0);
        }
    }
    
    public static void main(String[] args) {
        int[] arr = {12, 11, 13, 5, 6, 7};
        heapSort(arr);
        System.out.println(Arrays.toString(arr));
        // 输出: [5, 6, 7, 11, 12, 13]
    }
}