堆排序及其应用

完全二叉树的性质:如果i=1,则节点i是二叉树的根,无双亲;如果i>1,则其双亲节点是i/2向下取整,
堆是具有下列性质的完全二叉树:每个节点的值都大于或等于其左右孩子节点的值,称为大顶堆;或者每个节点的值都小于或等于其左右孩子节点的值,称为小顶堆。
按照层序遍历的方式给节点编号则满足ki>=k2i且ki>=k2i+1或者ki<=k2i且ki<=k2i+1。
堆排序就是利用堆(假设利用大顶堆)进行排序的算法,将待排序序列构造成一个大顶堆。此时整个序列的最大值就是堆顶的根节点,将它移走,然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次小值。如此反复执行便能得到一个有序的序列。
如何构造一个堆?

public void buildBigHeap(int []num) {
		int mid=num.length/2;
		for(int i=mid;i>0;i--) {
			heapAdjust(num,i,num.length);
		}
	}
	public void heapAdjust(int []num,int i,int len) {
		int temp=num[i-1];
		for(int j=2*i;j<=len;j*=2) {//遍历其子树,找到最大的节点放在根节点处
			if(j=num[j-1])
				break;
			num[i-1]=num[j-1];//将较大的节点放在根节点处
			i=j;
		}
		num[i-1]=temp;//将原来存放较大节点的位置存放较小的根节点
	}

下标之所以从mid开始,是因为编号mid~1之间对应的元素都存在孩子节点。
我们所谓的将待排序序列构建一个大顶堆其实就是从下往上,从右往左将每个非终端节点看做根节点,将其和其子树调整成大顶堆的过程。

堆排序完整实现
public void buildBigHeap(int []num) {
		int mid=num.length/2;
		for(int i=mid;i>0;i--) 
			heapAdjust(num,i,num.length);
		for(int i=num.length;i>1;i--) {
			int temp=num[i-1]; //将堆顶记录和当前未排序的子序列的最后一个记录交换
			num[i-1]=num[0];
			num[0]=temp;
			heapAdjust(num,1,i-1);//重新调整为大顶堆
		}
}
	public void heapAdjust(int []num,int i,int len) {
		int temp=num[i-1];//存储根节点的信息
		for(int j=2*i;j<=len;j*=2) {
			if(j=num[j-1])//如果根节点数值大于孩子节点则结束遍历
				break;
			num[i-1]=num[j-1];//找到当前最大的数值赋给根节点
			i=j;//i记录最大数值原始的存储位置
		}
		num[i-1]=temp;
	}

###题目描述
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

public int findKthLargest(int[] nums, int k) {
		int mid=nums.length/2;
		for(int i=mid;i>0;i--) 
			heapAdjust(nums,i,nums.length);
		//System.out.println(nums[0]);
		if(k==1)
			return nums[0];
		int count=k;
		for(int i=nums.length;i>1;i--) {
			if(count==1)
				break;
			int temp=nums[i-1];
			nums[i-1]=nums[0];
			nums[0]=temp;
			heapAdjust(nums,1,i-1);
			count--;
		}
		return nums[0];
    }
	public void heapAdjust(int []num,int i,int len) {
		int temp=num[i-1];//存储根节点的信息
		for(int j=2*i;j<=len;j*=2) {
			if(j=num[j-1])//如果根节点数值大于孩子节点则结束遍历
				break;
			num[i-1]=num[j-1];//找到当前最大的数值赋给根节点
			i=j;//i记录最大数值原始的存储位置
		}
		num[i-1]=temp;
	}

你可能感兴趣的:(LeetCode)