堆排序

两个条件

  1. 堆是完全二叉树

  2. 堆中父结点的值大于等于(或小于等于)子结点的值

数学关系

对于索引为i的父结点:

  1. 其父结点为(i-1)/2

  2. 其子结点分别为2i+1和2i+2

时间复杂度
nlogn

讲解视频
https://www.bilibili.com/video/BV1Eb41147dK?from=search&seid=3993837508839965022&vd_source=18f8edc7281037c531b04fe3548e2e10

代码

void heapify(vector<int>& nums, int n, int i)
{
    int l = 2 * i + 1, r = 2 * i + 2;
    int max = i;
    if (l < n && nums[l] > nums[max])
        max = l;
    if (r < n && nums[r] > nums[max])
        max = r;
    if (max != i)
    {
        swap(nums[max], nums[i]);
        heapify(nums, n, max);
    }
}

// 建立大根堆,从树的倒数第二层第一个结点开始
void buildHeap(vector<int>& nums, int n)
// 对每个结点进行 heapify 操作,然后向上走
{
    int start = (n - 2) / 2;
    for (int i = start; i >= 0; i--)
    {
        heapify(nums, n, i);
    }

    for (int i = 0; i < nums.size(); i++)
    {
        cout << nums[i] << " ";
    }
    cout << endl;
}

// 建立大根堆之后,每次交换最后一个结点和根结点(最大值),
// 对交换后的根结点继续进行 heapify (此时堆的最后一位是最大值,因此不用管他,n 变为 n-1)
void heapSort(vector<int>& nums, int n)
{
    buildHeap(nums, n);
    for (int i = 0; i < n; i++)
    {
        swap(nums[0], nums[n - i - 1]);
        heapify(nums, n - i - 1, 0);
    }
}

heapSort(A, A.size());
for (auto i : A)
{
    cout << i << " ";
}
cout << endl;
posted @ 2022-06-13 16:56  卯月十八  阅读(39)  评论(0)    收藏  举报