【数据结构和算法16】堆排序

        堆排序,顾名思义就是利用堆这个数据结构对数据项进行排序,前面提到过,堆数据结构中,节点大于或等于自己的子节点。那么我们可以将待排序的数据项依次添加到堆中,然后再依次取出根节点即可。从堆中取出的数据项是从大到小排列的。因为根节点永远是最大的,而堆中永远是取根节点。如果对堆这种数据结构不太了解的话,可以先看这篇博文:数据结构和算法之 堆,这里不再赘述。

下面我们来看看堆排序的实现(如果程序有不清楚的地方,也可以参考上面那篇博文)。

 

public class HeapSort {
	private int[] array;
	private int currentIndex;
	private int maxSize;
	public HeapSort(int size) {
		maxSize = size;
		array = new int[maxSize];
		currentIndex = 0;
	}
	//插入数据项,并排好序
	public void insertSort(int[] source) {
		for(int i = 0; i < source.length; i++) {
			array[currentIndex] = source[i]; //插入到节点尾
			tickedUp(currentIndex++); //向上重新排好序,使得满足堆的条件
		}
	}
	private void tickedUp(int index) {
		int parentIndex = (index - 1) / 2; //父节点的索引
		int temp = array[index]; //将新加的尾节点存在temp中
		while(index > 0 && array[parentIndex] < temp) {
			array[index] = array[parentIndex];
			index = parentIndex;
			parentIndex = (index - 1) / 2;
		}
		array[index] = temp;
	}
	
	//取出最大值
	public int getMax() {
		int maxNum = array[0];
		array[0] = array[--currentIndex];
		trickleDown(0);
		return maxNum;
	}
	private void trickleDown(int index) {
		int top = array[index];
		int largeChildIndex;
		while(index < currentIndex/2) { //while node has at least one child
			int leftChildIndex = 2 * index + 1;
			int rightChildIndex = leftChildIndex + 1;
			//find larger child
			if(rightChildIndex < currentIndex &&  //rightChild exists?
					array[leftChildIndex] < array[rightChildIndex]) {
				largeChildIndex = rightChildIndex;
			}
			else {
				largeChildIndex = leftChildIndex;
			}
			if(top >= array[largeChildIndex]) {
				break;
			}
			array[index] = array[largeChildIndex];
			index = largeChildIndex;
		}
		array[index] = top;
	}
}

 

        算法分析:堆中插入和取出的时间复杂度均为O(logN),所以堆排序算法的时间复杂度为O(NlogN),但是堆排序也需要额外的和待排序序列大小相同的存储空间。空间复杂度为O(N)。

        欢迎大家关注我的公众号:“武哥聊编程”,一个有温度的公众号~

        关注回复:资源,可以领取海量优质视频资料
        程序员私房菜

_____________________________________________________________________________________________________________________________________________________

-----乐于分享,共同进步!

-----更多文章请看:http://blog.csdn.net/eson_15

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值