【基础算法】排序-复杂排序之三(堆排序)
来源:互联网 发布:postfix ubuntu 编辑:程序博客网 时间:2024/06/11 04:33
归并排序的平均时间复杂度为O(NlogN),但是要占用空间,因此效率上并没有提升多少。
快速排序的平均时间复杂度为O(NlogN),但是最坏的情况,时间复杂度还是会到O(N^2)。
因此能不能有一种排序,时间复杂度为O(NlogN),最坏的情况时间复杂度也是O(NlogN)呢?
利用优先级队列中二叉堆的性质,我们考虑把一串无序的序列构建成堆,然后依次把最顶上的元素放到数组的最末尾,这样数组就可以从小到大排好序了。
因此我们采取两步法来实现堆排序
第一步:建堆
建堆的目的是为了把那些父节点比子节点小的元素沉降到它的相应位置。因此我们应该从父节点的最后一位开始依次向上遍历,直到顶点为止。
定理:父节点的最后一位 i 一定是元素总数N的一半,即i=N/2。利用的就是子节点=父节点*2或子节点=父节点*2+1。
建堆的过程是让N/2个元素依次沉降到相应位置,所以时间复杂度是(N/2)*logN
int N = array.length-1;// heap constructionfor (int i = N / 2; i >= 1; i--)sink(array, i, N);
第二步:堆排序
把最顶点和最后一位元素交换,然后将换到顶点的新元素沉降到合适位置。
时间复杂度是NlogN
while (N > 1) {exchange(array, 1, N--);sink(array, 1, N);}
这样堆排序就结束了。
以下是sink函数的实现
public static void sink(int[] array, int k, int N) {// N is the number of disorder elementswhile (2 * k <= N) {int j = 2 * k;if (j < N && more(array[j + 1], array[j]))j++;if (more(array[k], array[j]))break;exchange(array, j, k);k = j;}}public static boolean more(int v, int w) {return v > w;}public static void exchange(int[] array, int i, int j) {int temp = array[i];array[i] = array[j];array[j] = temp;}
通过堆排序,我们发现它几乎完成了时间复杂度为O(NlogN),最坏的情况时间复杂度也是O(NlogN)的效果,但是有一个问题在于这个排序依旧是一个不稳定的排序,能不能发明一个稳定的排序且有同样的效果,我们只能等待大师们的灵感了!
0 0
- 【基础算法】排序-复杂排序之三(堆排序)
- 【基础算法】排序-复杂排序之二(快速排序)
- 浅谈排序算法(三)之堆排序
- 排序算法三之堆排序
- 算法三之堆排序
- 算法三之堆排序
- 算法基础之排序篇-堆排序
- 基础算法系列(十七)排序算法之堆排序
- 算法基础之----堆排序
- 【基础算法】排序-简单排序之三(插入排序)
- Java排序算法(三):堆排序
- 排序算法(三):堆排序
- Java排序算法(三):堆排序
- Java排序算法(三):堆排序
- Java排序算法(三):堆排序 .
- 排序算法(三)-- 堆排序
- Java排序算法(三):堆排序
- (高效率排序算法三)堆排序
- Android新手环境搭建,HelloWorld
- Flex creationComplete等Application事件
- __blk_end_request源码分析
- SPECT、PET、CT与MRI成像原理及其特点的比较
- HDU 1524
- 【基础算法】排序-复杂排序之三(堆排序)
- Java中Vector、LinkedList和ArrayList的区别
- JAVA中HashMap和Hashtable区别
- RELIEF Feature Selection(RELIEF特征选择) Python实现
- java中int和string类型转换
- Java关键字final、static使用总结
- 【基础算法】位运算-找出奇特的数
- [Leetcode] Divide Two Integers
- Java基本概念:集合类(Collection)List/Set/Map... 的区别和联系