📜  堆排序的C ++程序(1)

📅  最后修改于: 2023-12-03 15:23:41.252000             🧑  作者: Mango

堆排序

堆排序是一种基于二叉堆的排序算法,在排序过程中将待排序的数据依次插入到一个二叉堆中,然后依次从堆中取出最大(最小)的元素放到数组中,直到堆为空为止。

算法描述
  1. 创建一个空的二叉堆(完全二叉树),依次将待排序的数据插入堆中;
  2. 将堆顶元素,也就是当前堆中的最大(最小)元素取出,放到数组的末尾;
  3. 将堆的大小减1,并对堆进行重建,重建后堆顶元素即为次大(小)的元素;
  4. 重复步骤2-3,直到堆为空。
代码实现
void heapify(vector<int>& nums, int n, int i) {
    int largest = i;
    int l = 2*i + 1;
    int r = 2*i + 2;

    if (l < n && nums[l] > nums[largest]) {
        largest = l;
    }

    if (r < n && nums[r] > nums[largest]) {
        largest = r;
    }

    if (largest != i) {
        swap(nums[i], nums[largest]);
        heapify(nums, n, largest);
    }
}

void heapSort(vector<int>& nums) {
    int n = nums.size();

    // 从最后一个非叶子节点开始构建最大堆
    for (int i = n/2 - 1; i >= 0; i--) {
        heapify(nums, n, i);
    }

    // 依次从堆顶取出元素放到数组末尾
    for (int i = n-1; i >= 0; i--) {
        swap(nums[0], nums[i]);
        heapify(nums, i, 0);
    }
}
算法复杂度
  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(1)
算法优缺点
  • 优点:稳定性较好,适用于大规模数据的排序
  • 缺点:实现较为复杂,无法进行原地排序,需要额外的空间。