堆排序
来源:互联网 发布:等一分钟网络歌曲女声 编辑:程序博客网 时间:2024/05/12 00:21
思想:将数组调整为一个堆,保证父节点不小于两个子节点,这样根节点(堆顶)就是所有元素中的最大值。不断取出根节点并重新调整堆,直到堆被取完即可完成排序。
技巧:
1.关于“不断取出根节点形成有序数组”,可以将堆顶(最大值)与堆的最后一个节点交换,然后缩小堆(排除已取出的节点),然后下沉堆顶到正确的位置即可得到新的已调整的堆;
2.构造堆有两种方式,一种是从堆顶往后遍历所有节点,每次都将当前节点与父节点进行比较,使其上浮到正确的位置;另一种是从最后一个非叶子节点开始往前遍历直到根节点,每次都将当前节点与子节点进行比较,使其下沉到正确的位置。
由于技巧1中也用到下沉法,所以使用第二种方法会更加方便,同时由于只需要从最后一个非叶子节点进行遍历,效率也更高。
实现代码如下:
void heapSort(int num[], int start, int end){//从最后一个非叶子节点开始往前调用sink调整堆//调用完之后该节点之后的节点都是已调整好的小堆//当根节点调用完成之后形成一个已调整好的大堆for(int i=(start+end-1)/2;i>=start;i--)sinkForHeapSort(num, i, start, end);//大顶堆//直到堆的大小为1,则数组升序排序完成for(int j=end;j>=start;){swap(num[start], num[j]);//将堆顶的元素(最大值)与堆的最后一个节点交换j--;//缩小堆sinkForHeapSort(num, start, start, j);//重新调整堆}}
代码中可以对num[]数组的任意区域(start~end)进行排序,因此父节点和子节点的下标满足下式:
(childPos+start-1)/2=parentPos
sinkForHeapSort的实现代码如下:
//对pos位置的元素进行调整,使其下降到正确的位置void sinkForHeapSort(int num[], int pos, int start, int end){//(childPos+start-1)/2=parentPosif(pos<start||start>end) return;int childPos=pos*2-start+1;//左边子节点的坐标while(childPos<end)//如果有左边子节点和右边子节点{if(num[childPos]<num[childPos+1]) childPos++;//如果右边子节点比较大,则用右边子节点与父节点进行比较if(num[pos]>=num[childPos])break;//如果父节点比子节点都要大,则退出循环swap(num[pos], num[childPos]);//如果父节点较小,则与较大的子节点交换pos=childPos;//继续往下沉childPos=pos*2-start+1;}//只有左边子节点时,直接与左边子节点进行比较if(childPos==end && num[pos]<num[childPos]) swap(num[pos], num[childPos]);}
0 0
- 堆及堆排序
- 堆/堆排序特点
- 【二叉堆、堆排序】
- 二叉堆 & 堆排序
- 二叉堆 & 堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆和堆排序
- 堆排序(最大堆)
- 堆和堆排序
- 堆和堆排序
- 堆及堆排序
- 堆和堆排序
- 堆与堆排序
- 使用swift集成移动广告聚合平台
- BZOJ1191(二分图匹配)
- UIImageView添加点击事件
- nim博弈 hdu2176 取(m堆)石子游戏
- 七种网卡绑定模式详解
- 堆排序
- Mybatis工作原理
- 第四篇 虚拟机类加载机制
- Java Sax解析xml
- 【Html】垂直居中-父元素高度确定的多行文本(方法一)
- 集合工具类CollectionUtils、ListUtils、SetUtils、MapUtils探究
- kafka编程模型
- ANT(重要思想!)
- hdu 4630 线段树+在线操作