🐵指尖猴全新升级
第10课:堆排序
🏃

堆排序

一边建堆一边出队,排序自然完成!

📖知识引入

🏗️建堆
从n/2号节点倒着到1号逐个下沉,O(n)就能建好大根堆
🎯排序思路
堆顶最大与末尾交换,堆规模减一,再把新堆顶下沉
📈O(n log n)
每次取最值花O(log n),取n次,稳定的高效排序
🏠原地排序
不需要额外数组,只在原数组里交换,省下宝贵内存
💡
建堆从n/2倒着来,因为下标大于n/2的节点全是叶子,天然不用下沉

🔍完整的堆排序

void sink(int h[], int n, int i) {   // 让 h[i] 下沉到位
    while (2 * i <= n) {
        int son = 2 * i;
        if (son + 1 <= n && h[son + 1] > h[son]) son++;
        if (h[i] >= h[son]) break;
        swap(h[i], h[son]);
        i = son;
    }
}

void heapSort(int a[], int n) {
    for (int i = n / 2; i >= 1; i--) sink(a, n, i);  // O(n) 建堆
    for (int i = n; i > 1; i--) {
        swap(a[1], a[i]);    // 当前最大值放到末尾
        sink(a, i - 1, 1);   // 剩余部分重新下沉
    }
}

先建大根堆,再反复交换堆顶与末尾并下沉。

🎯小测验

第1题:堆排序的总时间复杂度是?

第2题:建堆时从哪个下标开始下沉?

第3题:用大根堆堆排序,最终数组是?

📝本课知识点

  • ✓建堆从n/2倒着来
  • ✓堆顶换末尾再下沉
  • ✓堆排序O(n log n)
第10课完成!继续探索下一课吧 🚀