排序总结---堆排序
2017-03-18 22:07
155 查看
// // Created by liyuanshuo on 2017/3/17. // #include "heap_sort.h" /* * 堆的定义: * ki<k(2i+1) && k(i) < k(2i) | * 或者 * k(i) > k(2i) && k(i) > k(2i+1) * 若以一维数组存储堆,则堆对应一个完全二叉树,并且所有的非叶节点的值均不大于(或者不小于)其子女的值 * 根节点(堆顶元素)的值是最小的(或者最大的) * * 初始时把要排序的n个数的序列看作是一棵顺序存储的二叉树(一维数组存储二叉树),调整它们的存储序,使之 * 成为一个堆,将堆顶的元素输出,便得到n个元素中最小(或最大)的元素,这时根节点的数最小(或者最大), * 然后对后面的(n-1)个元素重新调整使之成为堆,输出堆顶元素,得到n个元素中次小(或此大)的元素,依此类推 * 直到只有两个节点的堆,并对它们作交换,最后得到n个节点的有序序列,这个过程称为堆排序。 * * */ /* * 因此,实现堆排序需解决两个问题: * * 1. 如何将n 个待排序的数建成堆 * * 2. 输出堆顶元素后,怎样调整剩余n-1 个元素,使其成为一个新堆 * * 首先讨论第二个问题:输出堆顶元素后,对剩余n-1元素重新建成堆的调整过程。 * 调整小顶堆的方法: * * 1)设有m 个元素的堆,输出堆顶元素后,剩下m-1 个元素。将堆底元素送入堆顶((最后一个元素与堆顶进行交 * 换),堆被破坏,其原因仅是根结点不满足堆的性质。 * * 2)将根结点与左、右子树中较小元素的进行交换。 * * 3)若与左子树交换:如果左子树堆被破坏,即左子树的根结点不满足堆的性质,则重复方法 (2). * * 4)若与右子树交换,如果右子树堆被破坏,即右子树的根结点不满足堆的性质。则重复方法 (2). * * 5)继续对不满足堆性质的子树进行上述交换操作,直到叶子结点,堆被建成。 * * 称这个自根结点到叶子结点的调整过程为筛选 */ /* * 再讨论对n 个元素初始建堆的过程。 * * 建堆方法:对初始序列建堆的过程,就是一个反复进行筛选的过程 * * 1)n 个结点的完全二叉树,则最后一个结点是第[n/2]个结点的子树。 * * 2)筛选从第[n/2]个结点为根的子树开始,该子树成为堆。 * * 3)之后向前依次对各结点为根的子树进行筛选,使之成为堆,直到根结点。 */ //从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。所以堆排序有两个 //函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。 /* * 已知H[s…m]除了H[s] 外均满足堆的定义 * 调整H[s],使其成为大顶堆.即将对第s个结点为根的子树筛选, */ // H是待调整的堆数组 // s是待调整的数组元素的位置 // length是数组的长度 void heap_adjust( int H[], int s, int len ) { int tmp = H[s]; int child = 2 * s + 1; while ( child < len ) { if( child+1 < len && H[child] < H[child+1] ) child++; if ( H[s] < H[child] ) { H[s] = H[child]; s = child; child = 2 * child + 1; } else break; H[s] = tmp; } } void build_heap( int H[], int len ) { for (int i = (len-1)/2 ; i >= 0 ; --i ) { heap_adjust (H, i, len); } } void heap_sort( int H[], int len ) { build_heap (H, len); for (int i = len-1; i > 0 ; --i) { int tmp = H[i]; H[i] = H[0]; H[0] = tmp; heap_adjust (H, 0, i); } }
相关文章推荐
- 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结
- 各种排序算法总结----基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- 面试珠玑 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结
- 排序总结:堆排序、快速排序、归并排序、基数排序
- 排序总结(三)之---堆排序
- 常用算法总结之排序(六)----堆排序
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- 冒泡排序、选择排序、堆排序、快速排序、插入排序算法复杂度分析与算法实现(自己总结与转)
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- 排序总结系列七:堆排序
- 八大排序算法:简单插入排序、冒泡排序、希尔排序、快速排序、堆排序、归并排序等总结。
- 【朝花夕拾之排序算法总结】 快速排序,堆排序总结
- 常用排序算法总结(三)----选择排序 堆排序
- 面试珠玑 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- 几种排序总结(上)——堆排序
- 各种排序总结(三)堆排序
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- 排序算法总结---树形选择排序,堆排序
- 排序总结JS版(冒泡排序、简单选择排序、快速插入排序、希尔排序、堆排序、快速排序)