排序算法java三--堆排序

堆排序 看张我百度的gif图片,了解大根堆的性质,那么你就可以读下面的代码了。代码中有详尽的解释。

 

public static void heapSort(int[] array) {
	int length = array.length - 1;

	initHeapSort(array, length);
	System.out.println("堆: " + Arrays.toString(array));

	for (int k = 0; k < array.length - 1; k++) {

		change(array, length, 0);
		length--;
		heapchange(array, length);

	}

}
private static void initHeapSort(int[] array, int length) {
	/** 
	 * 初始化大根堆,每次堆中添加一个数组的元素,用此元素与父节点比较交换,
	 *交换后父节点(此时是你添加的元素)与父节点的父节点比较,直到父节点为根节点结束比较,来保证大根堆。
	 */
	for (int j = 1; j <= length; j++) {
		int k = j;
		int father = (k - 1) / 2;
		while (father >= 0 && k > 0) {

			if (array[k] > array[father]) {
				change(array, father, k);
			}
			System.out.println("交换后数组: " + Arrays.toString(array) + "j: "
						+ j);
			k = father;
			father = (father - 1) / 2;
		}
	}
}


 

private static void heapchange(int[] array, int length) {
	/**
	 *  当堆稳定时,交换堆最后一个元素和第一个元素,保持最后一个元素不动(用最大下标 array.length --),
	 * 判断根节点左右孩子是否存在,并比较大小,最大的和父节点交换,然后保证没有交换的一支不动,调整交换过的堆使堆稳定。然后重复上述步骤。
	 */
	int father = 0;//从堆顶开始
	int leftChild = 2 * father + 1;
	int rightChild = leftChild + 1;
	while (leftChild <= length ) {//当父节点没有孩子节点,是叶子节点,跳出循环
		
		//比较父节点和他的孩子节点,如果有大于它的,判断是左孩子还是右孩子交换
		if (rightChild <= length && (array[leftChild] > array[father] ||								array[rightChild] > array[father])) {
				
		//判断 rightChild <=length 保证在没有右孩子节点时只比较左孩子节点。
			if (array[leftChild] > array[rightChild]) {
					
				change(array, father, leftChild);
				father = leftChild;
			}else {
					
				change(array, father, rightChild);
				father = rightChild;
			}
		}else if (array[leftChild] > array[father]) {
		//当父节点只有一个左孩子节点(叶子节点)时,交换完之后就可以跳出循环,
		//说明:对于完全二叉树,满足此条件的父节点的子节点一定是叶子节点
		
			change(array, father, leftChild);
			break;
					
		}else {
		//当父节点没有和孩子节点交换,那么父节点下移,令左孩子节点为新一任父节点
		//(说明:右孩子节点不一定有,左孩子节点可以有,如果没有的话,此节点为叶子节点while()条件本意就是在判断是否是叶子节点)
			father = 2 * father + 1;
		}
				
		leftChild = 2 * father + 1;
		rightChild = leftChild + 1;
	}
		

}
private static void change(int[] array, int max, int k) {

		int temp = array[max];
		array[max] = array[k];
		array[k] = temp;

		// array[max] ^= array[k];
		// array[k] ^= array[max];
		// array[max] ^= array[k];

	}



 

你可能感兴趣的:(排序算法java三--堆排序)