算法导论——堆排序

/*-----------------堆排序---------------------*/
	
	/**
	 * 时间复杂度O(NlgN)
	 */
	
	int heapSize=0;
	
	@Test
	public void heapSort(){
		int[] array={ 5, 2, 4, 6, 1, -1,8,7,3 ,99,0,78};
		//堆排序
		heapSort(array);
		//观察排序后数组
		System.out.println(Arrays.toString(array));
	}

	private void heapSort(int[] array) {
		//创建最大堆
		buildMaxHeap(array);
		
		//根据堆的性质,数组中第一个元素必然是最大值,将该最大值和数组最后的元素换位。
		//这样,一一交换,数组的最大值就逐渐排到了最后位置
		for(int i=array.length-1;i>0;i--){
			//将最大值交换到数组最后位置
			exchange(array,i,0);
			//由于末尾已经放置了最大值,这时可以忽略末尾一个元素,继续将第二大的元素放到末尾。。。
			heapSize--;
			//maxHeapify这个已经去掉一个元素的堆,目的是将最大的元素上移到数组第一个元素位置
			maxHeapify(array,0);
		}
	}

	private void maxHeapify(int[] array, int i) {
		//获取堆中该元素的左孩子位置和右孩子位置
		int l=left(i);
		int r=right(i);
		
		//初始化最大元素的就是i位置的元素
		int largest=i;
		
		//如果堆的左右孩子存在,并且有比他更大的,那么找出最大的那个
		if(l<=heapSize-1&&array[l]>=array[i]){
			largest=l;
		}
		
		if(r<=heapSize-1&&array[r]>=array[largest]){
			largest=r;
		}
		
		if(largest!=i){
			//如果i不是最大值,那么将i和最大值换位
			exchange(array, i, largest);
			//换位后,新的i索引处此时不见得可以满足堆性质,需要不断递归做验证
			maxHeapify(array, largest);
		}
	}

	private void buildMaxHeap(int[] array) {
		heapSize=array.length;
		//建立最大堆的过程其实就是将每个非叶子节点进行maxHeapify
		//从array.length/2+1开始,后面都是作为叶子节点存在
		for(int i=array.length/2-1;i>=0;i--){
			maxHeapify(array, i);
		}
		
		System.out.println("------"+Arrays.toString(array));
	}
	/**由于数组索引是从0开始计算,那么左右元素的位置应该处于i*2+1和i*2+2的位置 */
	private int right(int i) {
		return i*2+2;
	}
             private int left(int i) {
		return i*2+1;
	}

	private void exchange(int[] array, int i, int j) {
		int temp=array[i];
		array[i]=array[j];
		array[j]=temp;
	}



转载于:https://my.oschina.net/u/1378920/blog/414424

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值