堆排序

#include <stdio.h>
#include <algorithm>
using namespace std;

// 将元素i向下调整
void adjust_down(int sz[], int i, int len)
{
    int k;
    sz[0] = sz[i]; // sz[0]位置暂存
    for (k = i << 1; k <= len; k = k << 1)
    {
        if (sz[k + 1] > sz[k] && k < len) // 沿key较大的节点向下调整
            k++;
        if (sz[k] > sz[0]) // 筛选结束
        {
            sz[i] = sz[k];
            i = k;
        }
        else
            break;
    }
    sz[i] = sz[0];
}

// 建立大顶堆
void build_max_heap(int sz[], int len)
{
    for (int j = len / 2; j > 0; j--)
    {
        adjust_down(sz, j, len);
    }
}
// 直接插入排序
void heap_sort(int sz[], int len)
{
    build_max_heap(sz, len);
    // 由于大顶堆第一个元素为最大值, 将其放到最后即为其最终位置,将最后一个元素放到大顶堆根部在进行向下调整
    for (int i = len; i > 1; i--)
    {
        swap(sz[1], sz[i]);
        adjust_down(sz, 1, i - 1);
    }
}
// 堆也支持插入删除操作,由于堆顶元素为最大值(或最小值),删除堆顶元素时将堆的最后一个元素与堆顶交换,由于此时堆的性质被破坏,对堆顶进行向下调整
// 对堆进行插入操作时先将新节点放在堆的末端,在对这个新节点进行向上调整(下面这个函数为向上调整函数)
// 参数k为向上调整的节点,也为堆的元素个数
void adjust_up(int sz[], int k)
{
    sz[0] = sz[k];
    int i = k / 2;
    while (i > 0 && sz[i] > sz[0]) // 循环退出条件
    {
        sz[k] = sz[i];
        k = i;
        i = i >> 1;
    }
    sz[k] = sz[0];
}

int main()
{
    // 初始化数组, 由于树用数组一般从1开始存,故0号单元未用
    int a[] = {0, 5, 10, 8, 100, 50, -10, 60};
    //执行堆排序
    heap_sort(a, 7);
    // 输出排序结果
    for (int i = 1; i < 8; i++)
    {
        printf("%d%c", a[i], i == 7 ? '\n' : ' ');
    }
    return 0;
}

  

posted @ 2019-04-20 08:11  sqdtss  阅读(80)  评论(0编辑  收藏  举报