您的位置:首页 > 其它

堆排序算法

2018-02-23 17:43 190 查看

堆排序

堆排序利用了二叉树的结构
二叉树的原理和实现: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[/code] 
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: