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); } }