堆排序
来源:互联网 发布:洗牙多久一次 知乎 编辑:程序博客网 时间:2024/05/22 17:06
先对二叉堆(最大堆和最小堆)理解:(实现添加,删除)
二叉堆文章:http://www.cnblogs.com/skywang12345/p/3610187.html
1、添加
2、删除
堆排序文章:http://www.cnblogs.com/skywang12345/p/3602162.html
最大堆进行升序排序的基本思想:
① 初始化堆:将数列a[1…n]构造成最大堆。
② 交换数据:将a[1]和a[n]交换,使a[n]是a[1…n]中的最大值;然后将a[1…n-1]重新调整为最大堆。 接着,将a[1]和a[n-1]交换,使a[n-1]是a[1…n-1]中的最大值;然后将a[1…n-2]重新调整为最大值。 依次类推,直到整个数列都是有序的。
数组实现的二叉堆的性质:
在第一个元素的索引为 0 的情形中:
性质一:索引为i的左孩子的索引是 (2*i+1);
性质二:索引为i的右孩子的索引是 (2*i+2);
性质三:索引为i的父结点的索引是 floor((i-1)/2);
/* * (最大)堆的向下调整算法 * * 注:数组实现的堆中,第N个节点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。 * 其中,N为数组下标索引值,如数组中第1个数对应的N为0。 * * 参数说明: * a -- 待排序的数组 * start -- 被下调节点的起始位置(一般为0,表示从第1个开始) * end -- 截至范围(一般为数组中最后一个元素的索引) */void maxheap_down(int a[], int start, int end){ int c = start; // 当前(current)节点的位置 int l = 2*c + 1; // 左(left)孩子的位置 int tmp = a[c]; // 当前(current)节点的大小 for (; l <= end; c=l,l=2*l+1) { // "l"是左孩子,"l+1"是右孩子 if ( l < end && a[l] < a[l+1]) l++; // 左右两孩子中选择较大者,即m_heap[l+1] if (tmp >= a[l]) break; // 调整结束 else // 交换值 { a[c] = a[l]; a[l]= tmp; } }}/* * 堆排序(从小到大) * * 参数说明: * a -- 待排序的数组 * n -- 数组的长度 */void heap_sort(int * a, int n){ int i; // 从(n/2-1) --> 0逐次遍历。遍历之后,得到的数组实际上是一个(最大)二叉堆。 for (i = n / 2 - 1; i >= 0; i--) maxheap_down(a, i, n-1); // 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素 for (i = n - 1; i > 0; i--) { // 交换a[0]和a[i]。交换后,a[i]是a[0...i]中最大的。 swap(a[0], a[i]); // 调整a[0...i-1],使得a[0...i-1]仍然是一个最大堆。 // 即,保证a[i-1]是a[0...i-1]中的最大值。 maxheap_down(a, 0, i-1); }}int main(){ int array[] = {2,8,7,1,0,10,3}; int len = sizeof(array); heap_sort(array, len); return 0;}
0 0
- 堆及堆排序
- 堆/堆排序特点
- 【二叉堆、堆排序】
- 二叉堆 & 堆排序
- 二叉堆 & 堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆和堆排序
- 堆排序(最大堆)
- 堆和堆排序
- 堆和堆排序
- 堆及堆排序
- 堆和堆排序
- 堆与堆排序
- EditText不自动获取焦点
- 重装sourceInsight序列号问题
- Canvas浏览器兼容
- 某政府单位应用交付解决方案系列三
- Mac配置Tomcat
- 堆排序
- c++编译错误
- 1116. Come on! Let's C (20)
- aspx与ashx,asmx之间的参数传递与调用
- 基于netty-socketio的web推送服务
- 在 Ubuntu on Windows 下Webpack 错误:uv_interface_addresses解决
- opencv 中对图像旋转任意角度
- asp.net用NPOI导出Excel
- 关于Mysql索引的入门用法