堆排序的Java代码实现
作为一名经验丰富的开发者,我很高兴帮助你学习如何实现堆排序的Java代码。堆排序是一种高效的排序算法,基于二叉堆数据结构。下面我将给你介绍整个堆排序的流程,并提供相应的Java代码实现,以便你更好地理解和掌握。
堆排序流程
堆排序的主要步骤如下:
步骤 | 描述 |
---|---|
1. 构建最大堆 | 将待排序数组构建成一个最大堆 |
2. 交换根节点和最后一个节点 | 将最大堆中的根节点(最大值)与最后一个节点交换位置 |
3. 调整堆 | 对交换后的新堆进行调整,使其重新满足最大堆的性质 |
4. 重复步骤2和3 | 重复执行步骤2和3,直到堆中只剩下一个元素 |
5. 输出排序结果 | 输出排序结果,即得到有序数组 |
下面我们将逐步实现这些步骤。
代码实现
1. 构建最大堆
首先,我们需要编写代码来构建一个最大堆。这里我们使用数组来表示堆,根据堆的性质,父节点的索引为i
时,左孩子的索引为2*i+1
,右孩子的索引为2*i+2
。
private static void buildMaxHeap(int[] arr, int length) {
for (int i = length / 2 - 1; i >= 0; i--) {
heapify(arr, length, i);
}
}
2. 交换根节点和最后一个节点
在构建最大堆之后,我们将根节点(最大值)与最后一个节点进行交换。
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
private static void heapSort(int[] arr) {
int length = arr.length;
buildMaxHeap(arr, length);
for (int i = length - 1; i > 0; i--) {
swap(arr, 0, i);
heapify(arr, i, 0);
}
}
3. 调整堆
交换根节点和最后一个节点后,我们需要对剩余的堆进行调整,使其重新满足最大堆的性质。
private static void heapify(int[] arr, int length, int i) {
int largest = i; // 假设当前节点为最大值
int left = 2 * i + 1; // 左孩子节点索引
int right = 2 * i + 2; // 右孩子节点索引
// 如果左孩子节点大于根节点,将左孩子节点设为最大值
if (left < length && arr[left] > arr[largest]) {
largest = left;
}
// 如果右孩子节点大于当前最大值,将右孩子节点设为最大值
if (right < length && arr[right] > arr[largest]) {
largest = right;
}
// 如果最大值不是当前节点,交换当前节点和最大值,然后继续调整
if (largest != i) {
swap(arr, i, largest);
heapify(arr, length, largest);
}
}
4. 重复步骤2和3
在交换根节点和最后一个节点,并调整堆之后,我们需要继续重复这两个步骤,直到堆中只剩下一个元素。
5. 输出排序结果
最后,我们将排序结果输出。
public static void main(String[] args) {
int[] arr = {4, 10, 3, 5, 1};
heapSort(arr);
System.out.println("排序结果:" + Arrays.toString(arr));
}
总结
通过以上的代码实现,我们可以实现堆排序算法。堆排序的时间复杂度为O(nlogn