欢迎使用CSDN-markdown编辑器
2016-04-14 19:48
344 查看
#堆排序算法(利用最大堆)
基础知识:
1.堆的定义(最大堆)
一个大小为n的堆是一颗包含n个结点的完全二叉树,该树中的每个结点的关键字值大于等于其双亲结点的关键字值。
当这颗完全二叉树以顺序对方式存储时,事实上排成了结点序列(k0,k1,k2,k3,…,kn-1)。所以堆又可以定义为:n个元素的序列(k0,k1,k2,k3,…kn-1),当且仅当k[i]>=k[2i+1] && k[i] >=k[2i+2]时称为最大堆。(最小堆类似)
2.堆排序思想:
1>将初始序列构成最大顶堆
2>将堆顶元素heap[0]与最后一个元素交换,此时得到新的序列(heap[0],heap[1],heap[2],..heap[n-2]),heap[n-1]。其中heap[n-1]为最大元素,将不参与新的建堆过程
3>由于交换元素后,原序列将不满足堆性质,对上步生成的n-1个元素重新进行建堆过程,即重复(1),(2).
3.建堆与排序图解
(http://img.blog.csdn.net/20160414201101071)
(http://img.blog.csdn.net/20160414201119486)
(http://img.blog.csdn.net/20160414201158837)
(http://img.blog.csdn.net/20160414201222144)
(http://img.blog.csdn.net/20160414201245119)
建堆图解
4.可执行代码
5.注意的问题
1>建堆过程中,heap[(child-1)/2] = heap[child],这一句我开始理解为heap[r]=heap[child],其实这样是不对的,因为建堆过程中,有向下调整的过程,临时值temp = heap[r]并不是简单的和第一代子结点交换就行,而是一直向下调整,直到合适的位置
2>create_heap函数中的n代表的是最大索引,而不是关键字个数
3>每次建堆都要用到下调堆结构函数,索引i的子代结点的索引为
基础知识:
1.堆的定义(最大堆)
一个大小为n的堆是一颗包含n个结点的完全二叉树,该树中的每个结点的关键字值大于等于其双亲结点的关键字值。
当这颗完全二叉树以顺序对方式存储时,事实上排成了结点序列(k0,k1,k2,k3,…,kn-1)。所以堆又可以定义为:n个元素的序列(k0,k1,k2,k3,…kn-1),当且仅当k[i]>=k[2i+1] && k[i] >=k[2i+2]时称为最大堆。(最小堆类似)
2.堆排序思想:
1>将初始序列构成最大顶堆
2>将堆顶元素heap[0]与最后一个元素交换,此时得到新的序列(heap[0],heap[1],heap[2],..heap[n-2]),heap[n-1]。其中heap[n-1]为最大元素,将不参与新的建堆过程
3>由于交换元素后,原序列将不满足堆性质,对上步生成的n-1个元素重新进行建堆过程,即重复(1),(2).
3.建堆与排序图解
(http://img.blog.csdn.net/20160414201101071)
(http://img.blog.csdn.net/20160414201119486)
(http://img.blog.csdn.net/20160414201158837)
(http://img.blog.csdn.net/20160414201222144)
(http://img.blog.csdn.net/20160414201245119)
建堆图解
4.可执行代码
#include <stdio.h> #include <iostream> using namespace std; void create_heap(int *heap,int n); void adjust_down(int *heap,int r,int n); int main() { int arr[] = {16,7,3,20,17,8,13}; int size = 7; while(size>1){ create_heap(arr,size); int temp = arr[size-1]; arr[size-1] = arr[0]; arr[0] = temp; size--; } for(int i =0;i<7;i++) cout << arr[i] << " "; cout << endl; return 0; } void adjust_down(int *heap,int r,int n) { int child = 2*r + 1; int temp = heap[r]; while (child <= n) { if((child<n) && (heap[child+1] > heap[child])) child++; if(temp>heap[child]) break; heap[(child-1)/2] = heap[child]; child = 2 * child + 1; } heap[(child-1)/2] = temp; } void create_heap(int *heap,int n) { for(int i=(n-1)/2;i>-1;i--) { adjust_down(heap, i, n-1); } }
5.注意的问题
1>建堆过程中,heap[(child-1)/2] = heap[child],这一句我开始理解为heap[r]=heap[child],其实这样是不对的,因为建堆过程中,有向下调整的过程,临时值temp = heap[r]并不是简单的和第一代子结点交换就行,而是一直向下调整,直到合适的位置
2>create_heap函数中的n代表的是最大索引,而不是关键字个数
3>每次建堆都要用到下调堆结构函数,索引i的子代结点的索引为
2*i+1, 2*i+2
相关文章推荐
- 第七周
- Android之Zygote启动详解
- MySQL+Python:安装MySQL-python
- @Html.Raw()
- HttpClient的简单使用--HttpGET和HttpPost
- 链式A+B
- Oracle-20-is null使用&order by子句
- JS弹出模态窗口下拉列表特效
- 实验二 作业调度模拟程序
- 算法(读书笔记):4.图
- c++ json封装---解析
- Lua和C++交互详细总结
- [CSAPP]Bufbomb实验报告
- Mediaproxy 与 Rtpproxy
- 微信支付JSAPI开发——官方Demo的错误、自定义参数传递
- Ubuntu12.04 root登陆方法【保证有效】
- 同样的错误不能犯两次(八):恐惧心理
- Android.mk文件简单分析
- bzoj4034 [HAOI2015]T2
- Camera AIDL - BpCamera,AIDL