堆排序
来源:互联网 发布:linux 交叉编译ide 编辑:程序博客网 时间:2024/05/16 12:13
概述
堆,可以视为一颗完全二叉树,其节点之间满足父节点不小于(不大于)两个子节点的值,这样的堆被称为大(小)根堆。用数学符号表示为:
- 大根堆:A[parent(i)] >= A[i]
- 小根堆:A[parent(i)] <= A[i]
在堆排序中,需要能够快速的找到节点的父节点,及其左右孩子节点。例如数组A[0 … n],可以将下标与树的节点按照下图进行匹配。
通过上图的方式给树的节点与数组下标的建立对应关系,可以很容易的计算出节点的父节点、左孩子和右孩子节点的下标:
#define LEFT(i) (((i) << 1) + 1)#define RIGHT(i) (((i) << 1) + 2)#define PARENT(i) (((i) - 1) >> 1)
若是数组下标从1开始对应树的根节点则有:
#define LEFT(i) ((i) << 1)#define RIGHT(i) (((i) << 1) + 1)#define PARENT(i) ((i) >> 1)
堆排序的过程主要可以分为三个阶段:
- 建堆。建堆是利用堆化过程将一个大小为n的数组转换为最大(小)堆的过程。
- 堆化。堆化用于保持堆的特性,是堆排序中最为重要的过程。其思想是比较节点i和它左右孩子节点,并选择三者中最大(小)的元素。如果最大值不是节点i,则调换节点i与最大子节点的值,并递归的对子节点进行兑换过程。
- 排序。该操作是从堆中取出最大(小)元素,并通过堆化过程维持堆的特性。
堆排序的实现
#include <stdio.h>/**< 查找左孩子节点下标 */#define LEFT(i) (((i) << 1) + 1)/**< 查找右孩子节点下标 */#define RIGHT(i) (((i) << 1) + 2)/**< 查找父节点下标 */#define PARENT(i) (((i) - 1) >> 1)/* @brief 堆化,保持堆的性质 * @param A [in] 数组地址 * @param len [in] 数组元素个数 * @param i [in] 需要堆化的元素的下标 */static voidheapify(int *A, int len, int i){ int largest; int l, r; l = LEFT(i); r = RIGHT(i); largest = i; if (l < len && A[l] > A[largest]) { largest = l; } if (r < len && A[r] > A[largest]) { largest = r; } if (largest != i) { int tmp = A[i]; A[i] = A[largest]; A[largest] = tmp; heapify(A, len, largest); /* 递归的对孩子节点进行堆化操作 */ }}/* @brief 建立堆 * @param A [in] 数组地址 * @param len [in] 数组元素个数 */static voidbuild_heap(int *A, int len){ int i = PARENT(len - 1); while (i >= 0) { heapify(A, len, i); i--; }}/* @brief 堆排序 * @param A [in] 待排序数组地址 * @param len [in] 待排序数组元素个数 */void hsort(int *A, int len){ int tmp; build_heap(A, len); len--; while (len > 0) { tmp = A[0]; A[0] = A[len]; A[len] = tmp; heapify(A, len, 0); len--; }}void display(int *A, int len){ int i; for (i = 0; i < len; i++) { printf("%d ", A[i]); } printf("\n");}int main(){ int A[] = {10, 32, 43, 31, 2, 45, 12, 9, 71, 41}; int len = sizeof(A) / sizeof(A[0]); display(A, len); hsort(A, len); display(A, len); return 0;}
0 0
- 堆及堆排序
- 堆/堆排序特点
- 【二叉堆、堆排序】
- 二叉堆 & 堆排序
- 二叉堆 & 堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆和堆排序
- 堆排序(最大堆)
- 堆和堆排序
- 堆和堆排序
- 堆及堆排序
- 堆和堆排序
- 堆与堆排序
- ORA-00439 feature not enabled: Partitioning
- Linux常用命令课堂笔记
- Hdu 4568 Hunter【spfa最短路 tsp状态压缩】
- vim配置
- 二叉查找树中的删除
- 堆排序
- dubbo,zookeeper和springmvc整合
- SpringMVC学习笔记--(1)
- 【LeetCode-216】Combination Sum III
- Bootstrap 洼地
- ssh 自动登录脚本
- android 使用butterknife简化加载布局控件
- sha1/md5 代码
- __cplusplus