堆排序C++

#include <vector>
#include <iostream>
#include <stdio.h>
#define left(i) (2*i+1)
#define right(i) (2*(i+1))
using namespace std;


void swap(int &a, int &b)
{
    int c = a;
    a = b;
    b = c;
}
void Heapify(int array[], int len, int pos)
{
    if (pos >= len)
        return;
    if (right(pos) < len&&array[right(pos)] > array[pos])
    {
        if (array[right(pos)] >= array[left(pos)])
        {
            swap(array[right(pos)], array[pos]);
            Heapify(array, len, right(pos));
        }
        else
        {
            swap(array[left(pos)], array[pos]);
            Heapify(array, len, left(pos));
        }
    }
    else if (left(pos) < len&&array[left(pos)] > array[pos])
    {
        swap(array[left(pos)], array[pos]);
        Heapify(array, len, left(pos));
    }
}
void BuildHeap(int array[], int len)
{
    for (int i = len / 2; i >= 0; i--)
    {
        Heapify(array, len, i);
    }
}
void HeapSort(int array[], int len)
{
    BuildHeap(array, len);
    for (int i = len-1; i >=0; i--)
    {
        swap(array[0], array[i]);
        Heapify(array, i, 0);
    }
}
int main()
{
    int array[10] = { 3, 6, 4, 2, 9, 12, 13, 1, -2, 7 };
    HeapSort(array, 10);
    return 0;
}
<think>好的,用户想了解C++堆排序的实现示例。首先我需要回忆堆排序的基本原理。堆排序是一种基于二叉堆的排序算法,分为两个主要步骤:构建堆和调整堆。通常使用大顶堆来进行升序排序,或者小顶堆进行降序排序。 接下来,我需要确保提供的代码示例正确且符合C++语法。根据引用[3]和引用[4],堆排序的实现需要两个主要函数:HeapSort和HeapAdjust。HeapSort负责初始化堆结构并进行排序循环,而HeapAdjust用于调整堆以满足堆的性质。 用户可能需要详细的代码解释,所以代码中的注释很重要。例如,在HeapAdjust函数中,需要说明循环的条件以及交换节点的过程。另外,主函数中的示例使用数组来演示排序过程,这样用户可以直观地看到输入和输出。 还需要注意堆排序的时间复杂度分析,最好在回答中提到平均和最坏情况下的复杂度都是O(n log n),以及堆排序是不稳定的排序算法。这些信息能帮助用户更好地理解其性能和应用场景。 用户提供的引用中有提到堆排序与其他排序算法的比较,比如快速排序在特定情况下的性能问题。可能用户在实际应用中遇到了性能问题,想通过堆排序来优化。因此,在相关问题中,可以推荐堆排序的适用场景,比如数据量大或需要稳定性时。 最后,确保代码示例中的语法正确,比如循环的范围、数组索引是否正确。例如,在构建堆时,从最后一个非叶子节点开始,即i=length/2-1,这一点需要正确体现在代码中。此外,交换堆顶元素和末尾元素后,调整堆的范围需要逐渐缩小,避免重复处理已排序的元素。 总结一下,回答需要包含清晰的代码示例、分步解释、时间复杂度分析以及相关问题,帮助用户全面理解堆排序C++实现。</think>以下是C++实现堆排序的详细代码示例及分步解释: ### 堆排序实现步骤 1. **构建大顶堆**:从最后一个非叶子节点开始向上调整 2. **堆调整**:保持父节点值大于子节点值 3. **排序循环**:将堆顶元素交换至末尾,缩小堆范围后重新调整 ### C++代码实现 ```cpp #include <iostream> using namespace std; // 调整堆(大顶堆) void HeapAdjust(int* arr, int parent, int length) { int temp = arr[parent]; // 保存父节点值 int child = 2 * parent + 1; // 左子节点索引 while (child < length) { // 选择较大的子节点 if (child + 1 < length && arr[child] < arr[child + 1]) { child++; // 切换到右子节点 } // 父节点值最大时停止调整 if (temp >= arr[child]) break; // 将子节点值赋给父节点位置 arr[parent] = arr[child]; parent = child; // 移动到子节点位置继续调整 child = 2 * parent + 1; } arr[parent] = temp; // 最终放置原始父节点值 } // 堆排序主函数 void HeapSort(int* arr, int length) { // 构建初始大顶堆(从最后一个非叶子节点开始) for (int i = length/2 - 1; i >= 0; i--) { HeapAdjust(arr, i, length); } // 依次取出堆顶元素进行排序 for (int j = length - 1; j > 0; j--) { swap(arr[0], arr[j]); // 将最大值移到末尾 HeapAdjust(arr, 0, j); // 调整剩余元素为堆(范围缩小) } } // 测试示例 int main() { int arr[] = {3, 5, 3, 0, 8, 6, 1, 5}; int length = sizeof(arr)/sizeof(arr[0]); HeapSort(arr, length); cout << "排序结果: "; for (int i = 0; i < length; i++) { cout << arr[i] << " "; } return 0; } ``` ### 关键特性 1. **时间复杂度**:始终为$O(n \log n)$,无论数据是否有序[^4] 2. **空间复杂度**:$O(1)$,原地排序算法 3. **稳定性**:非稳定排序(交换操作可能导致相同元素顺序改变) 4. **适用场景**:大数据量排序、优先队列实现、需要保证最坏情况性能的排序需求 ### 性能对比 根据引用[1],当处理逆序数组时,快速排序会退化为$O(n^2)$时间复杂度,而堆排序仍保持$O(n \log n)$的性能优势。在LeetCode等算法测试中,堆排序常被用于规避快速排序的最坏情况问题。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值