二.堆排序
来源:互联网 发布:access sqlserver编程 编辑:程序博客网 时间:2024/06/05 02:47
堆排序
在堆排序中,使用了堆的数据结构,结构如下图:
这个(二叉)堆是一个数组,可以看成一个近似的完全二叉树,树上的每一个节点对应数组的一个元素,除了最底层外,该树是完全的,而且从左到右填充,其高度为log2n。在一个堆中,它的父节点i对应的子节点分别为2i跟2i+1,二叉堆可以分成最大堆跟最小堆,在最大堆中,某个节点的值最多与其父节点一样大,而最小堆刚好与最大堆相反,这里使用最大堆进行排序。
首先,我们通过一个maxHeap方法来维护节点i处最大堆的性质。
Java代码:
public static void maxHeap(int[] arr, int i){ int l = 2 * i + 1; int r = 2 * i + 2; int largest = 0; if (l <= arr.length - 1 && arr[l] > arr[i]){ largest = l; }else{ largest = i; } if (r <= arr.length - 1 && arr[r] > arr[largest]){ largest = r; } if (largest != i){ int temp = arr[i]; arr[i] = arr[largest]; arr[largest] = temp; maxHeap(arr, largest); } }
对于树高为h的节点,maxHeap的时间复杂度是O(h),也就是O(log2n)。
maxHeap方法是维护节点i处最大堆的性质,如果对堆的所有非叶节点从底往上得进行维护最大堆的性质,
那么我们就可以得到一个最大堆,
Java代码:
public static void buildMaxHeap(int[] arr){ for (int i = arr.length / 2; i >= 0; i--){ maxHeap(arr, i); } }
这里需要O(n)次调用maxHeap方法,因此buildMaxHeap的时间复杂度为O(nlog2n),但是不同的节点运行maxHeap的时间与该节点为根节点的树高有关,而且大部分节点的高度都很小,buildMaxHeap有一个更紧确的界:O(n)。
堆排序是利用最大堆的堆顶是整个堆中最大的节点的性质进行排序,每次让根节点跟最后一个叶子节点互换,然后把该堆的大小减一重新构建一个最大堆,重复该过程完成堆排序。
由于需要改堆的大小,所以改变maxHeap,最终的Java代码如下:
public static void heapSort(int[] arr){ int length = arr.length; buildMaxHeap(arr); for (int i = arr.length - 1; i >= 1; i--){ int temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; maxHeap(arr, 0, --length); } } public static void buildMaxHeap(int[] arr){ for (int i = arr.length / 2; i >= 0; i--){ maxHeap(arr, i, arr.length); } } public static void maxHeap(int[] arr, int i,int length){ while (i < length){ int l = 2 * i + 1; int r = 2 * i + 2; int largest = i; if (l <= length - 1 && arr[l] > arr[i]){ largest = l; } if (r <= length - 1 && arr[r] > arr[largest]){ largest = r; } if (largest != i){ int temp = arr[i]; arr[i] = arr[largest]; arr[largest] = temp; i = largest; }else{ return; } } }
算法分析:
1. 时间复杂度
可以看出最终排序时调用了一次buildMaxHeap,它的时间复杂度为O(n),然后又调用了n-1次maxHeap,而maxHeap的时间复杂度为O(log2n),所以最终堆排序的时间复杂度为O(nlog2n)。
2. 空间复杂度
堆排序具有空间原址性(任何时候都只需要常数个额外的元素空间存储临时的数据)。
测试:
接下来分别使用10000,100000,500000个随机数进行测试:
- 排序二--堆排序
- 排序二--堆排序
- 堆排序之二
- 堆排序二
- 堆排序(二)
- 二.堆排序
- 排序算法(二):堆排序
- 《算法导论》(二)--堆排序
- 算法练习二 堆排序
- 排序算法二-堆,希尔,合并排序
- 【算法导论】排序 (二):堆排序
- 排序算法之堆排序(二)
- Java排序算法(二):堆排序
- 排序算法之二 堆排序
- 排序算法(二)之堆排序
- 排序算法(二):快速,归并,堆排序
- 堆排序算法二(堆排序算法的应用)
- 【排序二】选择排序(选择排序&&堆排序)
- Windows下Nginx的启动、停止等命令
- js 空数组是true还是false
- mysql的常用操作总结(数据库常用操作)
- 函数指针
- 虚拟机网络连接的三种模式
- 二.堆排序
- 【AI前沿】机器阅读理解与问答·Dynamic Co-Attention Networks
- 这也许是最具珍藏价值的Oracle DBA生存宝典!
- Idea Maven项目搭建spring 框架
- 初识monkeyrunner
- Java方法
- 6数据库的连接
- 对不同激活函数在神经网络中的比较分析
- php 冒泡排序&快速排序