排序算法-堆排序

蔚落 2022-10-13 12:35 287阅读 0赞

堆是一个完全二叉树
堆排序是指利用堆这种数据结构所设计的一种排序算法
大顶堆:每个结点的值都大于或等于其左右孩子结点的值
arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
在这里插入图片描述
小顶堆:每个结点的值都小于或等于其左右孩子结点的值
arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]
在这里插入图片描述
堆排序的基本思想是:将待排序序列构造成一个大顶堆(小顶堆同理),此时,整个序列的最大值就是堆顶的根节点。 将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得 到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

堆排序的过程

1.将给定无序队列构成一个二叉堆(一般升序排序会将这个二叉堆调整成大顶堆,降序队列调整成小顶堆)
arr=4 6 8 5 9

在这里插入图片描述
2.从最后一个非叶子节点开始从左至右调整,上面的5,9,8都是叶子节点,所以从6开始
最后一个非叶子节点index=arr.length/2-1=5/2-1=1
arr[1]=6
把arr[1]和它的左右儿子(arr[12+1],arr[12+2])比较,把最大的调整到arr[1]的位置上
在这里插入图片描述
3.找到倒数第二个非叶子节点4,和它的左右子节点比较交换
在这里插入图片描述
4.交换指挥456顺序不正确继续调整
在这里插入图片描述
这是这已经是一个大顶堆了

5、将堆顶元素与末尾元素进行交换(交换后不参与重建),使末尾元素最大。然后继续调整堆,再次变成大顶堆后将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换,重建。

在这里插入图片描述

6.反复交换重建

在这里插入图片描述

在这里插入图片描述
代码实现

  1. public class HeapSort {
  2. public static void main(String[] args) {
  3. int[] arr = {
  4. 1,7, 6, 4, 3, 5, 2, 10, 9, 8};
  5. System.out.println("排序前:" + Arrays.toString(arr));
  6. sort(arr);
  7. System.out.println("排序后:" + Arrays.toString(arr));
  8. }
  9. public static void sort(int[] array) {
  10. // 1. 把无序数组构建成最大堆,从最后 非叶子节点开始
  11. for (int i = array.length / 2 - 1; i >= 0; i--) {
  12. adjustHeap(array, i, array.length);
  13. }
  14. // 2. 调整堆结构+交换堆顶元素与末尾元素,调整堆产生新的堆顶
  15. for (int i = array.length - 1; i > 0; i--) {
  16. // 最后1个元素和第1个元素进行交换
  17. int temp = array[i];
  18. array[i] = array[0];
  19. array[0] = temp;
  20. // “下沉”调整最大堆
  21. adjustHeap(array, 0, i);
  22. }
  23. }
  24. public static void adjustHeap(int[] array, int parentIndex, int length) {
  25. // temp 保存父节点值,用于最后的赋值
  26. int temp = array[parentIndex];
  27. int childIndex = 2 * parentIndex + 1;
  28. while (childIndex < length) {
  29. // 如果有右孩子,且右孩子大于左孩子的值,则定位到右孩子
  30. if (childIndex + 1 < length && array[childIndex + 1] >array[childIndex]) {
  31. childIndex++;
  32. }
  33. // 如果父节点大于任何一个孩子的值,则直接跳出
  34. if (temp >= array[childIndex]) {
  35. break;
  36. }
  37. //无须真正交换,单向赋值即可
  38. array[parentIndex] = array[childIndex];
  39. parentIndex = childIndex;
  40. //下一个左孩子
  41. childIndex = 2 * childIndex + 1;
  42. }
  43. array[parentIndex] = temp;
  44. }
  45. }

发表评论

表情:
评论列表 (有 0 条评论,287人围观)

还没有评论,来说两句吧...

相关阅读

    相关 排序算法——排序

    排序算法——堆排序 > 堆排序是利用堆这种数据结构所设计的一种排序算法。堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点

    相关 排序算法-排序

    堆是一个完全二叉树 堆排序是指利用堆这种数据结构所设计的一种排序算法 大顶堆:每个结点的值都大于或等于其左右孩子结点的值 arr\[i\] >= arr\[2i+1

    相关 排序算法-排序

    堆排序算法是建立在堆这种数据结构的基础上,其实堆听着很高端,其实很简单,就是一个二叉树,但是又特殊条件,就是其父节点比孩子节点都大(或都小)的堆称为最大堆(最小堆),瞬间感觉很

    相关 排序算法——排序

    前言 对于推排序它像合并排序而不像插入排序,堆排序的运行时间为O(nlogn)。像插入排序而不像合并排序,它是一种原地排序算法:在任何时候,数组中只有常数和元素存储在输入

    相关 排序算法排序

    一、前言     堆排序是一种选择排序。     选择排序:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止。 ----

    相关 排序算法排序

      相关博客: [排序算法:冒泡排序、插入排序、选择排序、希尔排序][Link 1] [排序算法:归并排序、快速排序][Link 2] [排序算法:桶排序、计数排序、基

    相关 排序算法---排序

    二叉堆是完全二叉树或者是近似完全二叉树。 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。 2.每个结点的左子树和右子树都是一个二