面试--算法排序(5)(堆排序)
2017-07-30 17:32
239 查看
堆排序也是选择排序的一种
堆的定义:
如果有一个关键码K={k1,k2,k3…..}把他的所有元素按照完全二叉树的顺序存储方式放在一个一维数组中。并且满足
ki<=k2i且ki<=k2i+1//小根堆
ki>=k2i且Ki>=K2i+1//大根堆
小根堆效果图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202012/16/97e376f4d6bb103dea533ec588c67700)
大根堆效果图
![](https://oscdn.geek-share.com/Uploads/Images/Content/202012/16/96d7bf611c825228c82aa24104127049)
堆排序:
若在输出堆栈的最大值之后,使得剩余n-1个元素的序列又建成一个堆,则得到n个元素中的次大值,如此反复执行,便能得到一个有序序列,这个过程称为堆排序
*堆排序解决的两个问题:
①如何建堆
②输出堆顶元素之后,如何调整新堆*
代码展示:
算法分析:
平均时间复杂度:O(N*logN)
空间复杂度:O(1)
稳定性:不稳定
堆的定义:
如果有一个关键码K={k1,k2,k3…..}把他的所有元素按照完全二叉树的顺序存储方式放在一个一维数组中。并且满足
ki<=k2i且ki<=k2i+1//小根堆
ki>=k2i且Ki>=K2i+1//大根堆
小根堆效果图:
大根堆效果图
堆排序:
若在输出堆栈的最大值之后,使得剩余n-1个元素的序列又建成一个堆,则得到n个元素中的次大值,如此反复执行,便能得到一个有序序列,这个过程称为堆排序
*堆排序解决的两个问题:
①如何建堆
②输出堆顶元素之后,如何调整新堆*
代码展示:
import java.util.*; public class HeapSort { public int[] heapSort(int[] A, int n) { int lastIndex = n - 1; buildMaxHeap(A, lastIndex);//建立最大堆 while(lastIndex > 0){ swap(A, 0, lastIndex); if(--lastIndex == 0)//只剩一个元素,就不用调整堆了,排序结束 break; adjustHeap(A,0,lastIndex); } return A; } public void buildMaxHeap(int[] arr, int lastIndex) { // 从最后一个元素的父节点开始进行调整,一直调整到根节点结束 int j = (lastIndex - 1) / 2; while (j >= 0) { int rootIndex = j; adjustHeap(arr, rootIndex, lastIndex); j--; } } public void adjustHeap(int[] arr, int rootIndex, int lastIndex) {//从根节点开始往下调整 int biggerIndex = rootIndex; int leftChildIndex = rootIndex * 2 + 1; int rightChildIndex = rootIndex * 2 + 2; if(rightChildIndex <= lastIndex){//如果右孩子存在,则左孩子一定存在 if(arr[rightChildIndex] > arr[rootIndex] || arr[leftChildIndex] > arr[rootIndex]){ //将子节点更大的元素下标赋值给biggerIndex biggerIndex = arr[rightChildIndex] > arr[leftChildIndex]?rightChildIndex:leftChildIndex; } } else if(leftChildIndex <= lastIndex){//保证左孩子存在,且不能越界 if(arr[leftChildIndex] > arr[rootIndex]){ biggerIndex = leftChildIndex; } } if(biggerIndex != rootIndex){ swap(arr, biggerIndex, rootIndex); adjustHeap(arr, biggerIndex, lastIndex); } } public void swap(int[] arr, int biggerIndex, int rootIndex) { int temp = arr[rootIndex]; arr[rootIndex] = arr[biggerIndex]; arr[biggerIndex] = temp; } }
算法分析:
平均时间复杂度:O(N*logN)
空间复杂度:O(1)
稳定性:不稳定
相关文章推荐
- 笔试面试最常涉及到的12种排序算法(包括插入排序、二分插入排序、希尔排序、选择排序、冒泡排序、鸡尾酒排序、快速排序、堆排序、归并排序、桶排序、计数排序和基数排序)进行了详解。每一种算法都有基本介绍、算
- 【程序员笔试面试必会——排序①】Python实现 冒泡排序、选择排序、插入排序、归并排序、快速排序、堆排序、希尔排序
- 算法基础:排序(四)——二叉堆、优先队列、堆排序——Python实现
- 第十五周——项目一—验证算法(6)选择排序之堆排序
- 【算法拾遗(java描述)】--- 选择排序(直接选择排序、堆排序)
- 算法 排序 python 实现--堆排序
- 算法学习记录-排序——堆排序
- 【基础算法】排序-复杂排序之三(堆排序)
- 【牛客网】直通bat-面试算法精品课_第2章 排序 2.8 希尔排序练习题(JAVA版)
- 【牛客网】直通bat-面试算法精品课_第2章 排序 2.13 小范围排序练习题(JAVA版)
- 面试算法(三十八)数字在排序数组中出现的次数
- 算法面试100题——1、把二元查找树转变成排序的双向链表
- 面试常见5个算法套装,4个排序+二分查找
- 面试算法:lg(k)时间查找两个排序数组合并后第k小的元素
- Java常见排序算法之堆排序
- 小范围排序(巧用堆排序) -- 算法小结
- 面试算法:如何利用堆排序实现系统的Timer机制
- 冒泡排序、选择排序、堆排序、快速排序、插入排序算法复杂度分析与算法实现(自己总结与转)
- 面试前的准备(java专业 ~学习算法排序以及查找)
- 算法——排序(六)堆排序