堆排序是一种基于堆数据结构进行的排序算法,使用了堆的特性来实现排序,具有稳定性和时间复杂度为O(nlogn)的优势。下面详细介绍Java中的堆排序过程:
1.创建最大堆(或最小堆)
在堆排序中,需要将待排序的序列先构建成一个最大堆(或最小堆)。最大堆的性质是每个结点的值都大于(或等于)其子节点的值,最小堆的性质是每个结点的值都小于(或等于)其子节点的值。创建最大堆的过程可以使用Java中的PriorityQueue类(默认情况下创建的是小根堆),或者手动实现。
手动实现时,可以使用数组来表示堆,以最大堆为例,对于任意一个下标为 i 的结点,它的左子节点下标为 2i+1,右子节点下标为 2i+2。从最后一个非叶子节点开始进行“下沉”操作,即把当前结点的值与其子节点的值进行比较,如果当前结点的值小于其子节点的值,则交换两个结点的值,重复该过程直到当前结点的值大于其子节点的值或者已经到达叶子节点。
2.堆排序
当堆构建完成后,堆顶的元素就是当前堆中的最大元素(或最小元素)。将堆顶元素与最后一个元素交换,此时最后一个元素就是当前序列中的最大元素(或最小元素),然后把堆的大小减1,再对堆顶元素进行“下沉”操作,直到堆的大小为1为止。
重复上述过程,直到所有的元素都被排序。最终得到的序列就是有序的。
下面是Java代码实现:
public static void heapSort(int[] arr) {
// 创建最大堆
for (int i = arr.length / 2 - 1; i >= 0; i--) {
heapify(arr, arr.length, i);
}
// 堆排序
for (int i = arr.length - 1; i >= 0; i--) {
// 将堆顶元素与末尾元素交换
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
// 对堆顶元素进行“下沉”操作
heapify(arr, i, 0);
}
}
// 将数组中的子树构建成最大堆(递归实现)
private static void heapify(int[] arr, int heapSize, int i) {
int largest = i; // 初始化最大值为当前结点
int left = 2 * i + 1;
int right = 2 * i + 2;
// 找到最大值
if (left < heapSize && arr[left] > arr[largest]) {
largest = left;
}
if (right < heapSize && arr[right] > arr[largest]) {
largest = right;
}
// 如果最大值不是当前结点,则交换两个结点的值,并重新构建子树
if (largest != i) {
int temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;
heapify(arr, heapSize, largest);
}
}
本文介绍了基于堆数据结构的堆排序算法,具有稳定性和O(nlogn)的时间复杂度。详细阐述了在Java中实现堆排序的过程,包括创建最大堆(或最小堆),可使用PriorityQueue类或手动实现;以及堆排序的具体步骤,还给出了Java代码实现。
1329

被折叠的 条评论
为什么被折叠?



