堆排序

   堆的排序分为两个阶段。在堆的构造阶段中,我们将原始数组重新组织排进一个堆中;然后在下沉排序阶段,我们从堆中取出所有的元素并得到排序结果。

1.堆的构造

   由N个给定的元素构造一个堆,只需从左至右遍历数组,用swim()(参见优先队列)保证扫描指针左侧的所有元素已经是一颗堆有序的完全树既可(时间复杂度O(NlgN))。更高效的方法是从右至左用sink()函数构造子堆,数组的每个位置都已经是一个子堆的根结点,sink()对这些子堆也适用,这样的话就能递归地建立起堆的秩序。

//堆排序
 public class HeapSort
{
   public static void sort(Comparable[] a)
  {
	int N = a.length;
	for (int k = N/2; k >= 1; k--)
	{
		sink(a,k,N);
	}
	while(N>1)
	{
		exch(a,1,N--);
		sink(a,1,N);
	}
  }
 private static void sink(Comparable[] a, int k, int N)
 {
	while(k*2 <= N)
	{
		int j = 2*k;
		if (j < N && less(a,j,j+1))  j++;
		if (!less(a,k,j)) break;
		exch(a,k,j);
		k = j;
	}
}
 private static  void  exch(Comparable[] a, int i, int j)
   {       
           //本来是a[i]和a[j],数组用的是a[1]到a[N],而实际上大小为N的数组的表示是a[0]到a[N-1]
           //所以i跟j相应地减1
          Comparable temp = a[i-1];
	   a[i-1] = a[j-1];
	   a[j-1] = temp;
  }
   private static  boolean less(Comparable[] a, int i,int j)
   {
      //理由同上
     return (a[i-1].compareTo(a[j-1])) < 0;
   }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值