堆排序的实现

堆排序看了很久,并未实现。这次把编程珠玑和课本上的方法拿来一起温习

//堆排序

#include<iostream>
using namespace std;
void sift(int a[],int low,int high)
{
 int i=low,j=2*i;
 int tmp=a[i];
 while(j<=high)
 {
  if(j<high&&a[j]>a[j+1])
   j++;        //j指示孩子结点中较小的节点
  if(tmp>a[j])   
  {
   a[i]=a[j];      //a[j]调整到双亲结点
   i=j;            //修改i和j的值,继续向下筛选
   j=2*i;          
  }
  else
   break;
 }
 a[i]=tmp;
}
void SiftSort(int a[],int n)
{
 int tmp;
 for(int i=n/2;i>0;i--) //生成初始的小根堆
  sift(a,i,n);
 for(int i=n;i>1;i--)
 {
  tmp=a[1];    //将最后一个元素和第一个元素交换
  a[1]=a[i];
  a[i]=tmp;
  
  sift(a,1,i-1); //交换后可能不满足堆的性质,需要重新生成i-1个元素的堆
 }

}
void siftup(int a[],int n) //假定a[1]~a[n-1]已是小根堆,从堆的最底层插入新的结点,有可能破坏堆的性质,所以需要从堆底向堆顶判断是否符合堆的性质,
                           //若不符合则要交换结点,使其满足堆的性质
{
 int tmp;
 int p;
 int i=n;
  while(1)
  {
   if(i==1)
    break;
   p=i/2;
   if(a[i]>a[p])
    break;
   else
   {
    tmp=a[i];
 a[i]=a[p];
 a[p]=tmp;
   }
   i=p;
  }
}
void siftdown(int a[],int n) //将堆的第一个元素和最后一个元素交换后,可能造成第一个元素到倒数第二个元素不满足堆的性质。需要从上到下维护堆
{
 int j,tmp, i=1;
 while(i<n)
 {
  j=2*i;
  if(j>n)
   break;
  if(j+1<=n&&a[j]>a[j+1])
   j++;
  if(a[i]>a[j])
  {
   tmp=a[i];
   a[i]=a[j];
  a[j]=tmp;
  }
  else
   break;
   i=j;  
 }

}
void SiftSort2(int a[],int n)
{
 int tmp;
  for(int i=1;i<=n;i++)
   siftup(a,i);
  for(int i=n;i>=1;i--)
  {
   tmp=a[1];
  a[1]=a[i];
  a[i]=tmp;
  
  siftdown(a,i-1);
 
  }
}
int main()
{
 int a[]={0,2,3,4,1,9,7,8,6,5};
 SiftSort(a,9);
 cout<<"第一种堆排序方法:"<<endl;
 for(int i=1;i<=9;i++)
  cout<<a[i]<<" ";
 cout<<endl;
 cout<<"第二种堆排序方法:"<<endl;
 int b[]={0,2,3,4,1,9,7,8,6,5};
 SiftSort2(b,9);
 for(int i=1;i<=9;i++)
  cout<<b[i]<<" ";
 return 0;
}

posted @ 2013-09-17 15:41  sumile  阅读(176)  评论(0)    收藏  举报