HeapSort 堆排序

堆排序 - Heap Sort, 它和Merge Sort - 归并排序很像,但是不同于Insertion Sort - 插入排序,因为它的运行时间为 O(nlogn). 可是它又和Insertion Sort很类似,但是不同于Merge Sort, 因为它是In Place的。

综上所述,heap sort是整合了insertion sort 和 merge sort的优点的算法即 In Place的运行时间为 O(nlogn) 的排序算法。


1. 使用的数据结构

     heap sort使用的是数组数据结构进行操作,但是为了更好的理解我们将数据转化成二叉树 。如下图


2. 两种不同属性的heap sort, 一种是max-heap 如上图,任意根节点的值都大于它的左孩子和右孩子。另一种是min-heap, 任意根节点的值都小于它的左孩子和右孩子。


3. 如何保持heap sort中heap的max-heap或者min-heap的这种属性呢?

 (以max-heap作为例子)采用 max-heapify 操作。如下图,

 

4. max-heapify 是什么原理呢? 

 max-heapify 是一个方法, 这个方法的输入是两个变量 max-heapify(int[] array, int index). 做的就是一件事即 从输入的index开始使从该index为起点的较大值的子树满足max-heap属性。

如上图中, 对应的输入为 max-heapify (Array, 1). 就是从 节点 4开始, 使节点4以及它的子树满足max-heap属性。


5. 为什么要使用max-heapify?

 max-heapify是为build-max-heap做准备的,因为max-heapify只是对二叉树的中单个点进行操作使其满足max-heap属性,而build-max-heapify就是对整体的树进行max-heapify使整体满足max-heap属性。 注意的是当我们进行build-max-heapify的时候,我们不必从最后一个节点开始, 我们可以从中间节点开始, 因为中间节点之后的节点都是中间节点之前节点的孩子。 

6. build-max-heapify 会有什么好处?

  当在5中我们完成了build-max-heapify之后, 我们得出一个二叉树,该二叉树有一个很重要的性质:第一个节点是最大值!并且二叉树中的所有节点满足max-heap原则, 而且最后一个节点也肯定是一个较小值. 我们可以使用这些性质完成 heap sort 算法 即 每次把第一个节点和最后一个节点进行互换,互换之后对第一个节点进行max-heapify处理.  如下图

            

7. HeapSort算法的应用

  PriorityQueue 就是一个对heap sort 的很好的实现。

代码使用Java 实现: GitHub - HeapSort  (算法实现中的heap_size 指的是: 我们想要做操作的对应的数组大小!)


有问题欢迎指出!


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
堆排序是一种经典的排序算法,使用堆数据结构实现。下面是CSDN堆排序的具体步骤: 1. 首先,将待排序的序列构建成一个最大堆。最大堆要求父节点的值大于等于其子节点的值。构建最大堆的方法是从最后一个非叶子节点开始,逐个向上调整节点使其满足堆的性质。 2. 构建最大堆后,将堆顶元素(最大值)与堆的最后一个元素交换位置,并将堆的大小减1,相当于将最大值移到了数组的最后位置。 3. 交换位置后,重新调整堆,使其满足最大堆的性质。 4. 重复步骤2和步骤3,直到堆的大小为1。 以下是CSDN堆排序的示例代码: ```java public class HeapSort { public static void heapSort(int[] array) { int n = array.length; // 构建最大堆 for (int i = n / 2 - 1; i >= 0; i--) { heapify(array, n, i); } // 交换堆顶元素与最后一个元素,并重新调整堆 for (int i = n - 1; i >= 0; i--) { int temp = array[0]; array[0] = array[i]; array[i] = temp; heapify(array, i, 0); } } private static void heapify(int[] array, int n, int i) { int largest = i; int left = 2 * i + 1; int right = 2 * i + 2; // 找到左右子节点中的最大值 if (left < n && array[left] > array[largest]) { largest = left; } if (right < n && array[right] > array[largest]) { largest = right; } // 如果最大值不是根节点,则交换位置,并继续调整堆 if (largest != i) { int temp = array[i]; array[i] = array[largest]; array[largest] = temp; heapify(array, n, largest); } } public static void main(String[] args) { int[] array = {4, 2, 6, 8, 3, 1, 9, 5, 7}; heapSort(array); System.out.println(Arrays.toString(array)); } } ``` 以上就是CSDN堆排序的排序过程。堆排序的时间复杂度为O(nlogn),其中n为待排序序列的长度。该排序算法是一种不稳定的排序算法,因为在调整堆的过程中会交换元素的位置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值