堆排序是利用“堆”这种数据结构而设计的一种排序算法,它是一种选择排序。

堆排序的基本思想:
1、将待排序的含n个元素的序列构造成一个堆(至于用大根堆还是小根堆,自己酌情用),整个序列的根节点就是最值节点。
2、将该最值节点与末尾节点交换,此时末尾节点就是最值节点。
3、不处理末尾得到的最值节点,将剩余n-1节点重新构造成一个堆,重复以上步骤,取出每个堆中的最值节点,就能得到一个有序序列。

下面我用java代码按步骤写一下这个排序过程

1.构造一个序列,我用数组,在里面填10个50以下的随机数。

int[] arr = new int[10];
Random rd = new Random();
for(int i=0;i<arr.length;i++){
	arr[i] = rd.nextInt(50);// 用50及以下的随机整数作为数组元素
}

2.写一个方法,该方法能将数组元素构造成一个大根堆,利用递归的方式

/**
* 构造大根堆
 * @param arr 要排序的数组
 * @param length 当前要调整的元素个数
 * @param startIndex 当前要调整的起始位置
 */
private static void toMaxHead(int[] arr, int length, int index) {
	// 获取左右子节点的索引
	int leftNodeIndex = 2*index+1;
	int rightNodeIndex = 2*index+2;
	
	// 获取最大节点所对应的的索引
	int maxIndex = index; // 用于获取最大节点所对应的的索引
	
	if(leftNodeIndex < length && arr[maxIndex] < arr[leftNodeIndex]){
		maxIndex = leftNodeIndex;
	}
	if(rightNodeIndex < length && arr[maxIndex] < arr[rightNodeIndex]){
		maxIndex = rightNodeIndex;
	}
	
	// 如果index已经改变,索引对应的节点交换位置
	if(maxIndex != index){
		int t = arr[index];
		arr[index] = arr[maxIndex];
		arr[maxIndex] = t;
		toMaxHead(arr, length, maxIndex); // 递归
	}
}

3.main中循环调用该方法,获得初始大根堆

// 定义开始调整的位置
int startIndex = (arr.length-1)/2;
// 第一次循环调整
for(int i = startIndex;i>=0;i--){
	toMaxHead(arr,arr.length,i);
}

4.将第一次调整后的大根堆的根节点和最后一个节点进行交换,然后继续循环处理剩下的节点

for(int i = arr.length-1;i>0;i--){
	int t = arr[0];
	arr[0] = arr[i];
	arr[i] = t;
	// 交换之后,在循环中随着i的减小缩小数组长度
	toMaxHead(arr, i, 0); // 继续递归将剩余i个数组元素排成大根堆
}

完整代码:

public class StackSort {

	public static void main(String[] args) {
		int[] arr = new int[10];
		Random rd = new Random();
		for(int i=0;i<arr.length;i++){
			arr[i] = rd.nextInt(50);// 用50及以下的随机整数作为数组元素
		}
		System.out.println("排序前:"+Arrays.toString(arr));
		// 定义开始调整的位置
		int startIndex = (arr.length-1)/2;
		// 第一次循环调整
		for(int i = startIndex;i>=0;i--){
			toMaxHead(arr,arr.length,i);
		}
		// 将第一次调整后的大根堆的根节点和最后一个节点进行交换
		for(int i = arr.length-1;i>0;i--){
			int t = arr[0];
			arr[0] = arr[i];
			arr[i] = t;
			// 交换之后,在循环中随着i的减小缩小数组长度
			toMaxHead(arr, i, 0); // 继续递归将剩余i个数组元素排成大根堆
		}
		System.out.println("排序后:"+Arrays.toString(arr));
	}
	/**
	 * 构造大根堆
	 * @param arr 要排序的数组
	 * @param length 当前要调整的元素个数
	 * @param startIndex 当前要调整的起始位置
	 */
	private static void toMaxHead(int[] arr, int length, int index) {
		// 获取左右子节点的索引
		int leftNodeIndex = 2*index+1;
		int rightNodeIndex = 2*index+2;
		
		// 获取最大节点所对应的的索引
		int maxIndex = index; // 用于获取最大节点所对应的的索引
		
		if(leftNodeIndex < length && arr[maxIndex] < arr[leftNodeIndex]){
			maxIndex = leftNodeIndex;
		}
		if(rightNodeIndex < length && arr[maxIndex] < arr[rightNodeIndex]){
			maxIndex = rightNodeIndex;
		}
		
		// 如果index已经改变,索引对应的节点交换位置
		if(maxIndex != index){
			int t = arr[index];
			arr[index] = arr[maxIndex];
			arr[maxIndex] = t;
			toMaxHead(arr, length, maxIndex); // 递归
		}
	}
}

运行情况:

java堆初始化 java实现堆_java堆初始化