堆排序算法

堆排序

堆排序利用了二叉树的结构
二叉树的原理和实现:http://blog.csdn.net/qq_21358401/article/details/79329523

堆排序的大致过程:
1. 排序选出n个数中最大的一个
2. 在剩下的n-1个数中继续排序选最大的一个
3. 知道只剩下一个最小的数

堆排序用到的堆并非不是管理内存的堆栈,这里的堆指的是一种完全二叉树(叶节点
只出现在最下层或次下层).
堆分为大顶堆(根节点的值大于左节点和右节点)和小顶堆(根节点的值小于左节点和右节点).

排序

假设有n个数据
1. 递归调整(将最大值/最小值调整到堆顶)
2. 将堆顶的最大/最小值取出 继续调整排序剩下的n-1个节点

调整
void adjust(int *a, int size, int index) {
    int max = index; // 根节点序号为i
    int left  = index * 2 + 1; // 根节点的左节点序号则为 2*i + 1
    int right = index * 2 + 2; // 根节点的右节点序号则为 2*i + 2

    // 如果左节点或者右节点比根节点小 则和根节点交换值
    if (left < size && a[left] < a[max])
        max = left;
    if (right < size && a[right] < a[max])
        max = right;

    if (max != index) {
        // 递归调整子节点
        swap(&a[max], &a[index]);
        adjust(a, size, max);
    }
}

排序
void sort(int *a, int size) {
    int i = 0;

    // 0到size/2-1 是堆中非叶子节点的序号(包括0 也就是堆顶节点)
    // 这样做也就是把所有带子节点的节点都进行一次调整
    // 选出最大/最小值到堆顶
    for (i = size / 2 - 1; i >= 0; i--) {
        adjust(a, size, i);
    }

    log("heap top:%d", a[0]); // 上述调整后堆顶是最大/最小值

    // 堆顶节点提取到数组尾部
    // i--;  剩下的i个数据继续调整 重复选出最大/最小值到堆顶
    for (i = size -1; i >= 1; i--) {
        swap(&a[0], &a[i]);
        adjust(a, i, 0);
    }
}

参考blog

http://blog.csdn.net/lzuacm/article/details/52853194

示例代码

int main() {
    log("heap sort test");

    int a[] = {12, 14, 13, 33, 35, 57};
    log("sizeof a:%d", array_size(a));
    sort(a, 6);

    int i = 0;
    for (; i < array_size(a); i++) {
        log("idx:%d val:%d", i, a[i]);
    }

    return 0;
}

git repo:
https://github.com/sliver-chen/codingutil/tree/master/algorithm/head_sort
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值