using namespace std; /*除第i个节点,i的下面的节点都已经满足堆的定义时,调用headWithHead之后,成为最大堆。*/ void heatWithHead(int *p,int i,int m) { int tmp,j; tmp=p[i]; for(j=2*i+1;j<m;j=2*j+1){ if(j<m-1&&p[j]<p[j+1]){ j++; } if(tmp>p[j]){ break; } p[i]=p[j]; i=j; } p[i]=tmp; }
//heat是一个完整的建堆过程,执行后得到一个有序的,堆(上小下大) void heat(int *p,int m){ int j,tmp; for (j=(m-1)/2;j>=0;j--){/*这里从最后一个节点的父节点进行第一个函数操作(叶子节点的节点构成的树肯定满足最大堆定义,循环结束后得到一个最大堆)*/ heatWithHead(p,j,m); } for(j=m-1;j>0;j--){/*循环将最大堆第一个最大的树和堆最后一个数交换,最后的数变成最大的数,利用第一个函数,将除最大的数外的堆变成最大堆,循环得到有序堆*/) tmp=p[j]; p[j]=p[0]; p[0]=tmp; heatWithHead(p,0,j); } }
//测试代码 int main() { int arr[10]={1,9,5,85,65,44,74,43,76,75}; int i; heat(arr,10); for(i=0;i<10;i++){ cout<<arr[i]<<" "; } return 0; }
//这是改良后,模板函数的方法,思路一样
template <typename T> void adjustDui(T *p,int start,int size) { int i; T tmp=p[start]; for(i=start*2+1;i<size;i=2*i+1){ if(i+1<size&&p[i]<p[i+1]){ i++; } if(tmp>p[i]){ break; } p[start]=p[i]; start=i; } p[start]=tmp; } template<typename T,int size> void duiPaiXu(T *p) { int i; T tmp; for(i=(size-1)/2;i>=0;i--){ adjustDui<T>(p,i,size); } for(i=size-1;i>0;i--){ tmp=p[0]; p[0]=p[i]; p[i]=tmp; adjustDui<T>(p,0,i); } }