【算法】堆排序
2015-11-12 12:45
197 查看
堆排序
上一篇博客讲了堆这种数据结构,它提供了一种接口getMax接口,好消息是获得最大值的时间复杂度仅仅为O(1),删除最大值delMax也仅仅需要O(lgn)的时间(删除后需要调整至满足堆的性质需要O(lgn)),因此联想到之前的选择排序算法,每次从剩下的未排序元素中找到极值元素,将其放入对应的位置。由于一般的选择排序在寻找最大值时需要遍历数组,遍历数组的复杂度为O(n),因此造成了时间的浪费,如若将待排序的数组进行一系列整理,例如将其整理成有特点的堆这种数据结构。那么我们有理由相信,能将选择排序的时间复杂度降低到O(nlgn)
堆排序算法
具体的堆排序算法如下,很容易理解HEAP-SORT(A) // 利用数组A建最大堆 CREATE-HEAP(A) for i= n-1 to 1 exchange A[0] A[i] heap.size=heap.size-1; // 由于交换可能会导致不满足堆的有序性,需要调整:下滤 Adjust(A,0)于是在Heap类中添加一个排序的方法
public void heapSort(int[] heapArr) { createHeapFloyd(heapArr);// 下标为0----n-1中保存着一个最大堆 for (int i = n - 1; i >= 1; i--) { swap(heapArray, 0, i); n--; // 调整新的堆的顺序性 percolateDown(0); } }当调用heapSort后里面的堆已经被排好序了。然而这样还不够直接,如果将建堆时的操作改成
public void createHeapFloyd(int[] heapArr) { // System.arraycopy(heapArr, 0, heapArray, 0, heapArr.length); heapArray = heapArr; n = heapArr.length; for (int i = (n - 1) >> 1; i >= 0; i--) { percolateDown(i); } }
即直接将待排序的数组赋给堆中维护的数组,性能更好。
堆排序的性能
这样调用堆排序后,数组已经有序,并且还不需要额外的内存空间,除了交换产生固定的空间消耗以外。即空间复杂度为O(1)堆排序是一种不稳定的排序算法,这是显然的,因为如果找到未排序部分的元素会和后面的交换,已排序部分的指针前移,再次有一个相同元素会放在前面,故而和原始顺序相反。
测试
public static void main(String[] args) { Heap heap = new Heap(100); int arr[] = new int[]{10,5,13,8,6,78,4,6}; heap.heapSort(arr); for (int i : arr) { System.out.print(i + " "); } }
输出序列为
4 5 6 6 8 10 13 78
相关文章推荐
- JavaScript演示排序算法
- 在命令行用 sort 进行排序
- 堆排序
- 文件遍历排序函数
- C#选择排序法实例分析
- C#插入法排序算法实例分析
- C#实现Datatable排序的方法
- SQLSERVER的排序问题结果不是想要的
- Windows Powershell排序和分组管道结果
- C#通过IComparable实现ListT.sort()排序
- C#堆排序实现方法
- C#选择法排序实例分析
- SQL学习笔记四 聚合函数、排序方法
- C#对list列表进行随机排序的方法
- 一根网线内的8根线哪4根是传输数据的,哪四根是防干扰的
- 算法之排序算法的算法思想和使用场景总结
- C#折半插入排序算法实现方法
- SQL进行排序、分组、统计的10个新技巧分享
- C++实现位图排序实例
- 基于C++实现的各种内部排序算法汇总