加速堆排序的C++实现
来源:互联网 发布:电饭煲推荐 知乎 编辑:程序博客网 时间:2024/06/15 09:07
加速堆排序比普通堆排序减少了一半的比较次数,但是网上似乎没有加速堆排序的具体C++实现,这里参照《计算机算法——设计与分析导论》(BG)给出AcceleratedHeapSort的C++实现,通过了OJ上面的测试,如果有可以优化或者需要改进的地方请多多指教。(其中被注释掉的代码用于输出调试信息)
#include <iostream>#include <cmath>using namespace std;/* 输出数组 */void print(int *ar, int n){ for(int i=0;i<n;i++) cout << ar[i] << " "; cout << endl;}/* 普通堆排序的fixHeap函数,建堆时需要用到 */void fixHeap(int *ar, int heapSize, int root, int K){ int left = 2*root+1; int right = 2*root+2; if(left>heapSize-1) //判断root是否为叶子节点 ar[root] = K; else { int largerSubHeap; if(left==heapSize-1) //无右子树 largerSubHeap = left; else if(ar[left]>ar[right]) //左子树较大 largerSubHeap = left; else //右子树较大 largerSubHeap = right; if(K>=ar[largerSubHeap]) //若K比最大子树根的值大,则直接插入 ar[root] = K; else //若K没有最大子树根的值大,则将K向下移动 { ar[root] = ar[largerSubHeap]; fixHeap(ar,heapSize,largerSubHeap,K); } }}/* 建堆 */void constructHeap(int *ar, int heapSize, int root){ int left = 2*root+1; int right = 2*root+2; if(left>heapSize-1) //判断root是否为叶子节点 return; else { constructHeap(ar,heapSize,left); //左子树 constructHeap(ar,heapSize,right); //右子树 fixHeap(ar,heapSize,root,ar[root]); //向下调整 }}/* 下降到hStop高度,返回hStop高度对应的空位,hStop一般设置为原先高度的1/2 */int promote(int *ar, int hStop, int root, int h) { int vacStop; int left = root*2+1; //左子女 int right = root*2+2; //右子女 if(h<=hStop) //高度已经降到了预先设定的高度hStop vacStop = root; else if(ar[right]>=ar[left]) { ar[root] = ar[right]; vacStop = promote(ar,hStop,right,h-1); } else { ar[root] = ar[left]; vacStop = promote(ar,hStop,left,h-1); } return vacStop;}/* 将空位从vacant向上移动,合适的时候停下来,不合适继续向上,直到root */void bubbleUpHeap(int *ar, int root, int K, int vacant){ if(vacant==root) ar[vacant] = K; else { int parent = (vacant-1)/2; if(K<ar[parent]) //合适则放置K ar[vacant] = K; else //不合适则将parent结点向下移动,继续向上寻找合适的位置 { ar[vacant] = ar[parent]; bubbleUpHeap(ar,root,K,parent); } }}/* 加速堆排序的核心函数 */void fixHeapFast(int *ar, int K, int root, int h, int heapSize){ if(h==0) ar[root] = K; else if(h==1) //类似fixHeap的处理 { int left = root*2+1; int right = root*2+2; if(left>heapSize-1) //若left超出了heapSize,则直接将K赋给root并返回 { ar[root] = K; return; } int largerSubHeap; if(left==heapSize-1) //无右子树 largerSubHeap = left; else if(ar[left]>ar[right]) //左子树较大 largerSubHeap = left; else //右子树较大 largerSubHeap = right; //cout << " root=" << root << ",K=" << K << ",largerSubHeap=" << largerSubHeap << endl; if(K>=ar[largerSubHeap]) //若K比最大子树根的值大,则直接插入 ar[root] = K; else //若K没有最大子树根的值大,则将K向下移动 { ar[root] = ar[largerSubHeap]; ar[largerSubHeap] = K; //cout << " "; //print(ar,heapSize); } } else { int hStop = h/2; int vacStop = promote(ar,hStop,root,h); //高度为h/2处空位所在位置 int vacParent = vacStop/2; if(K>=ar[vacParent]) //若K大于当前空位的父结点,则父结点下移,K向上移动;root结点本身不移动 { ar[vacStop] = ar[vacParent]; bubbleUpHeap(ar,root,K,vacParent); } else fixHeapFast(ar,K,vacStop,hStop,heapSize); }}/* 加速堆排序的接口函数 */void accelHeapSort(int *ar, int n){ constructHeap(ar,n,0); //cout << "constructed: "; //print(ar,n); for(int heapSize=n-1;heapSize>0;heapSize--) { int K = ar[heapSize]; ar[heapSize] = ar[0]; fixHeapFast(ar,K,0,log10(heapSize)/log10(2),heapSize); //print(ar,n); }}int main(){ int n; cin >> n; int *p = new int [n]; for(int i=0;i<n;i++) cin >> p[i]; accelHeapSort(p,n); print(p,n);}
1 0
- 加速堆排序的C++实现
- 堆排序的C实现
- 堆排序的实现(c++)
- 堆排序的实现-C语言
- 堆排序的C语言实现
- 【C++】CLRS上的堆排序实现
- 堆排序的c语言实现
- 堆排序的C语言实现
- C语言堆排序的实现
- 排序算法的C语言实现-堆排序
- 常见排序算法的C语言实现之堆排序
- 排序之堆排序的C语言实现
- 堆排序C语言实现
- 堆排序C语言实现
- 堆排序C语言实现
- 堆排序C语言实现
- 堆排序--C语言实现
- C语言实现堆排序
- LeetCode题解(Week 5) 452. Minimum Number of Arrows to Burst Balloons
- 考试(一)
- 深入 Android 源码系列(一)
- 洛谷 P1119 灾后重建
- 在WEB编程中response.sendRedirect()传汉字参数乱码问题
- 加速堆排序的C++实现
- 【机器学习 基本概念】泊松分布与美国枪击案
- Spring+Dubbo+MyBatis+Linner分布式Web开发环境搭建(二)
- python发送邮件
- jfree chart-时序图
- 后缀数组【倍增计数排序求sa】poj1743
- 可以在main函数之前执行的函数
- Time
- select查询语句执行顺序