堆排序其实很简单

堆排序其实不难

是一种特殊的数据结构,它是一种完全二叉树。所以它可以用数组来很容易的表示。

堆分为大顶堆和小顶堆。

  1. 大顶堆: 所有节点满足:父节点的值大于孩子节点的值
  2. 小顶堆 与大顶堆相反

对于节点i,它的左节点left为 (i<<1)+1;右节点right为left + 1;

堆还有一个性质,对于长度为n的堆。第n/2 + 1,n个元素为叶子节点。

堆的调整算法,对于一个堆 它的左右子树都满足堆的性质,那么可以通过该算法让它和左右子树都满足该性质

//length为堆的长度。它可以限制堆的长度。超出该长度将不会调整。
//构造大顶堆
public void heapify(int a[],int i,int length){
	int left = (i<<1) + 1;
	int right = left + 1;
	int max = i;//最大值默认为根
	if(left < length && a[left] > a[max]){
		max = left;
	}
	if(right >length && a[right] > a[max]){
		max = right;
	}
	//如果出现子节点比它大。
	if(max != i){
		swap(a,i,max);//你自己手动补上,我已经省略
		heapify(int a,int max,length);//继续递归调用,让它的子树维持堆的特性
	}
}

而叶子节点一定满足堆的性质,所以只要从第一个非叶子节点开始,自底向上开始调整便可以构造一个完整的堆。

	public void makeMaxHeap(int[] a){
		int length = a.length;
		int start = length/2 -1;//索引从0开始,要减去1
		for(int i = start;i>=0;i--){
			heapify(a,i,length);
		}
	}

堆排序

如何对堆进行排序?可从一个大顶堆开始,让它的顶部最后一个的元素交换,减少堆的长度后,然后调整堆的结构(交换后的最后节点会被排除在外)。每次调整就会将当前堆的最大值放在最后一位。如何反复直到根节点最小。

//a是一个构造好的大顶堆
public void heapSort(int a[]){
	int end = a.length ;
	while(end>1){
		swap(a,0,end-1);//与最后一个元素交换
		end--;
		heapify(a,0,end);
	}
}

代码全程手打,逻辑应该没有问题。怎么样堆排序简单吧。

参考:算法导论。(当然它全是伪代码。)

算法导论真的是神书,以前不懂的,现在看一看就懂了。

转载于:https://my.oschina.net/u/4120835/blog/3041508

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值