排序:堆排序

堆排序的基本思想是:html

        将待排序序列构形成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。而后将剩余n-1个元素从新构形成一个堆,这样会获得n个元素的次小值。如此反复执行,便能获得一个有序序列了。java

算法过程:算法

步骤一 构造初始堆。将给定无序序列构形成一个大顶堆(通常升序采用大顶堆,降序采用小顶堆)。数组

步骤二 将堆顶元素与末尾元素进行交换,使末尾元素最大。而后继续调整堆,再将堆顶元素与末尾元素交换,获得第二大元素。如此反复进行交换、重建、交换。code

 

/**
 * 堆排序(此方法最后获得的是升序的数组)
 * @param elements
 */
public static void heapSort(int[] elements) {
	int lastParentNodeIndex = 0;
	for(int tempLength = elements.length; tempLength > 1; tempLength--) {
		// 步骤1.构建大顶堆
		lastParentNodeIndex = (tempLength >> 1) - 1;
		for(int i = lastParentNodeIndex; i >= 0; i--) {
			// 从第一个非叶子结点从下至上,从右至左调整结构
			adjustHeap(elements, i, tempLength);
		}
		System.out.println("构建大顶堆:"+Arrays.toString(elements));
		// 交换堆顶元素与末尾元素
		swapElement(elements, 0, tempLength-1);
		System.out.println("交换堆顶元素与末尾元素:"+Arrays.toString(elements));
		System.out.println("-----------------------------------------------------");
	}
}

private static void adjustHeap(int[] elements, int parentNodeIndex, int length) {
	int leftNodeIndex = (parentNodeIndex << 1) + 1;
	int rightNodeIndex = leftNodeIndex + 1;
	if((length - 1) >= rightNodeIndex) {
		// parentNodeIndex指定的节点有左右两个子节点
		// 先比较左右连个子节点的元素大小,取大的子节点与父节点比较,若子节点的元素大于父节点,则把这两个元素交换
		if(elements[leftNodeIndex] >= elements[rightNodeIndex]) {
			if(elements[leftNodeIndex] > elements[parentNodeIndex]) {
				swapElement(elements,leftNodeIndex, parentNodeIndex);
				adjustHeap(elements, leftNodeIndex, length);
			}
		} else {
			if(elements[rightNodeIndex] > elements[parentNodeIndex]) {
				swapElement(elements, rightNodeIndex, parentNodeIndex);
				adjustHeap(elements, rightNodeIndex, length);
			}
		}
	} else if((length - 1) >= leftNodeIndex) {
		// parentNodeIndex指定的节点只有左边一个个子节点
		// 直接比较左边子节点与父节点的大小,若子节点的元素大于父节点,则把这两个元素交换
		if(elements[leftNodeIndex] > elements[parentNodeIndex]) {
			swapElement(elements,leftNodeIndex, parentNodeIndex);
			adjustHeap(elements, leftNodeIndex, length);
		}
	} else {
		// 元素下标超出了参数length-1,什么事都不用作
	}
}
private static void swapElement(int[] elements, int i, int j) {
	int temp = elements[i];
	elements[i] = elements[j];
	elements[j] = temp;
}

调用方法:htm

public static void main(String[] args) {
	int[] array = {82 ,31 ,29 ,71, 72, 42, 64, 5, 110};
	heapSort(array);
}

结果:blog

构建大顶堆:[110, 82, 64, 71, 72, 42, 29, 5, 31]
交换堆顶元素与末尾元素:[31, 82, 64, 71, 72, 42, 29, 5, 110]
-----------------------------------------------------
构建大顶堆:[82, 72, 64, 71, 31, 42, 29, 5, 110]
交换堆顶元素与末尾元素:[5, 72, 64, 71, 31, 42, 29, 82, 110]
-----------------------------------------------------
构建大顶堆:[72, 71, 64, 5, 31, 42, 29, 82, 110]
交换堆顶元素与末尾元素:[29, 71, 64, 5, 31, 42, 72, 82, 110]
-----------------------------------------------------
构建大顶堆:[71, 31, 64, 5, 29, 42, 72, 82, 110]
交换堆顶元素与末尾元素:[42, 31, 64, 5, 29, 71, 72, 82, 110]
-----------------------------------------------------
构建大顶堆:[64, 31, 42, 5, 29, 71, 72, 82, 110]
交换堆顶元素与末尾元素:[29, 31, 42, 5, 64, 71, 72, 82, 110]
-----------------------------------------------------
构建大顶堆:[42, 31, 29, 5, 64, 71, 72, 82, 110]
交换堆顶元素与末尾元素:[5, 31, 29, 42, 64, 71, 72, 82, 110]
-----------------------------------------------------
构建大顶堆:[31, 5, 29, 42, 64, 71, 72, 82, 110]
交换堆顶元素与末尾元素:[29, 5, 31, 42, 64, 71, 72, 82, 110]
-----------------------------------------------------
构建大顶堆:[29, 5, 31, 42, 64, 71, 72, 82, 110]
交换堆顶元素与末尾元素:[5, 29, 31, 42, 64, 71, 72, 82, 110]
-----------------------------------------------------

 

参考文档:排序

http://www.javashuo.com/article/p-wtyhbkog-dg.htmlelement

https://mp.weixin.qq.com/s/vgpKzmEjuJkhFy-NfpvURQ文档

相关文章
相关标签/搜索