排序算法:堆排序-Java实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法:堆排序-Java实现相关的知识,希望对你有一定的参考价值。
排序算法(二):堆排序-Java实现
首先对堆排序有个整体的认识,堆排序是一个不稳定的排序算法,其平均时间复杂度为O(nlogn),空间复杂度O(1)。
那么何为堆排序呢?所谓堆排序是借助于堆的概念来完成的排序算法,其是选择排序中的一种,因此通过选择排序来理解堆排序会更加容易一些
下面我们来看一下堆的概念,其实堆又是借助于二叉树的概念来定义,对于堆分为大顶堆和小顶堆两种,下面用数学表示式来精确的描述如下:
假设我们使用array数组来存储堆,因为大顶堆表述为 array[i] >=array[2*i+1] && array[i] >= array[2*1+2] , 小顶堆表示为array[i] <=array[2*i+1] && array[i] <= array[2*1+2], 但是值的注意的是array[2*i+1] 与array[2*i+2] 之间没有大小约束关系
对于堆的基本定义我们已经很清晰了,下面我们将详细的介绍一下堆排序的思路
堆排序的整体思路如下(以大顶堆为例说明,小顶堆同理哈)
- 根据大定堆的概念array[0]始终是最大的,因此与array[array.length-1]进行交换,此时就形成了 array[0].... array[array.length-2] 的无序数组和 array[array.length-1] 的有序数组
- 在1中形成的 array[0].... array[array.length-2] 无序数组中破坏了堆的特性,因此需要一次调整,调整从array.length-1处开始
-
- 首先找到array.length-1 父亲节点,如果有左右孩子,进行比较进行交换,依次循环往前进行处理
3. 依照按照1,2步骤循环进行,直到排序完成
Java 实现代码逻辑如下:
1 public class HeapSort { 2 3 public static void main(String[] args) { 4 int[] array = new int[]{5, 3, 6, 2, 1, 9, 4, 8, 7}; 5 6 HeapSort heapSort = new HeapSort(); 7 heapSort.heapSort(array); 8 9 for (int i = 0; i < array.length; i++) { 10 System.out.print(array[i]+" "); 11 } 12 } 13 14 15 public void heapSort(int[] array) { 16 17 for (int i = 0; i < array.length; i++) { 18 // 将array[array.length-1-i]创建为堆 19 createMaxHeap(array, array.length - 1 - i); 20 // 因为大顶堆,所以最大值始终处于array[0], 21 // 交换array[0]与array[array.length-1-i] 22 swap(array, 0, array.length - 1 - i); 23 } 24 } 25 26 // 调整成堆 27 private void createMaxHeap(int[] array, int lastIndex) { 28 // 从当前位置的父亲节点 29 for (int i = (lastIndex - 1) / 2; i >= 0; i--) { 30 // 记录当前的位置节点 31 int k = i; 32 // 条件成立,则说明有孩子节点,此时判断是否满足堆的特性 33 while (2 * k + 1 <= lastIndex) { 34 // 默认左孩子为最大 35 int biggerIndex = 2 * k + 1; 36 // 在判断一下看是否有右孩子 37 if (biggerIndex < lastIndex) { 38 // 如果存在右孩子,并且右孩子大,则将默认索引加1 39 if (array[biggerIndex] < array[biggerIndex + 1]) { 40 biggerIndex++; 41 } 42 } 43 44 // 此时在跟父亲节点作比较 45 if (array[k] < array[biggerIndex]) { 46 swap(array, k, biggerIndex); 47 } else { // 如果不小于则结束本次循环,下一个节点的比较 48 break; 49 } 50 } 51 } 52 } 53 54 // 交换两个元素 55 private void swap(int[] data, int i, int j) { 56 if (i == j) { 57 return; 58 } 59 data[i] = data[i] + data[j]; 60 data[j] = data[i] - data[j]; 61 data[i] = data[i] - data[j]; 62 }
博客描述不对之处,请指正,希望给大家带来帮助,谢谢。
以上是关于排序算法:堆排序-Java实现的主要内容,如果未能解决你的问题,请参考以下文章