博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
堆排序原理(图)及java版代码
阅读量:4078 次
发布时间:2019-05-25

本文共 3304 字,大约阅读时间需要 11 分钟。

数据结构中的堆可看做完全二叉树结构,其特性是任意一父节点的值分别大于或小于其左右子节点的值(大根堆和小根堆)

完全二叉树一般采用数组结构来表示,根据完全二叉树特性任意一父节点的值都大于(或小于)其子节点的值可知其第一个节点的值为树中的最大(最小)值,则每次将第一个父节点的值放到数组最后则可以实现排序。

首先来看一个图例:

堆排序

图中详细描述了如何将一组数构建成一个完全二叉树以及通过二叉树来排序,图里已写的很清楚了,这里就不赘述了。

下面来看java版实现:

** * Created by white * USER : WHITE . * DATE : 2016/9/13 0013 下午 9:21. * HeapSortUtil.java:堆排序工具类 */public class HeapSortUtil {
/** * 构造完全二叉树 * * @param array */ private void buildHeap(int[] array) { int lastParentIndex = getLastParentIndex(array.length); /********************************************* * 从最后一个父节点开始将树中最大值换到父节点上 *********************************************/ for (int i = lastParentIndex; i >= 0; i--) { buildTree(array, array.length, i); } } /** * 排序传入的父节点树及改动过的子树 * * @param array * @param parentIndex */ private void buildTree(int[] array, int maxIndex, int parentIndex) { int leftChildIndex = getLeftChildIndex(parentIndex); int rightChildIndex = getRightChildIndex(parentIndex); /*************************************************************** * 左右节点最大值大于父节点则与父节点交换值并刷新交换后的子节点树 **************************************************************/ int maxValueIndex = parentIndex; if (leftChildIndex < maxIndex && array[maxValueIndex] < array[leftChildIndex]) { maxValueIndex = leftChildIndex; } if (rightChildIndex < maxIndex && array[maxValueIndex] < array[rightChildIndex]) { maxValueIndex = rightChildIndex; } if (maxValueIndex != parentIndex) { swapVaule(array, maxValueIndex, parentIndex); buildTree(array, maxIndex, maxValueIndex); } } /** * 取堆的第一个节点和最后一个节点对换并重排剩下的树 * * @param array */ private void sortHeap(int[] array) { for (int i = array.length - 1; i > 0; i--) { swapVaule(array, 0, i); buildTree(array, i, 0); } } /** * 取堆的最后一个父节点 * * @param arryLength 数组长度 * @return 返回树的最后一个父节点坐标 */ private int getLastParentIndex(int arryLength) { return (arryLength >> 1) - 1; } /** * 获取左子节点的下标 * * @param parentIndex * @return */ private int getLeftChildIndex(int parentIndex) { return (parentIndex << 1) + 1; } /** * 获取右子节点的下标 * * @param parentIndex * @return */ private int getRightChildIndex(int parentIndex) { return (parentIndex << 1) + 2; } /** * 交换数组中元素 * * @param array * @param sourceIndex * @param targetIndex */ private void swapVaule(int[] array, int sourceIndex, int targetIndex) { int temp = array[sourceIndex]; array[sourceIndex] = array[targetIndex]; array[targetIndex] = temp; }}

通过以下方法调用:

public static void main(String[] args) {        HeapSortUtil util = new HeapSortUtil();        int[] array = new int[]{
54, 21, 32, 85, 65, 45, 12, 20, 35, 96}; //构造完全二叉树 util.buildHeap(array); //排序 util.sortHeap(array); for (int i : array) { System.out.print(i + ", "); } }

输出结果:

12, 20, 21, 32, 35, 45, 54, 65, 85, 96,

从结果看出已实现了堆排序,另代码里都有详细的注释,这里就不多解释了,有不明白的地方欢迎留言指出。


我的博客:blog.scarlettbai.com

你可能感兴趣的文章
一个真正好的无人机应该是需要自己慢慢去调参的,别人的默认参数是可以飞但是可能达不到perfect的效果。
查看>>
carzepony也在想往FreeRTOS上迁移
查看>>
可以买个好点的电烙铁
查看>>
ACfly调参记录(包括ACfly-F330和ACfly-T265)
查看>>
一定记得每飞几次或者隔一天要把螺丝和浆帽拧一次,确实会松的
查看>>
《多旋翼无人飞行器嵌入式飞控开发指南》里基于FreeRTOS的无人机软件框架
查看>>
我感觉无人机借助于激光雷达实现定点悬停的效果应该好于光流才是
查看>>
思岚A1的SDK其实很好读懂,每个函数清晰明了,可以直接调用
查看>>
六角铜柱的型号
查看>>
pixhawk无GPS时可以在定高或者自稳模式下解锁起飞(见过多次别人说到)
查看>>
pixhawk(PX4)的一些论坛网站(包括中文版的PX4用户手册和PX4开发手册)
查看>>
串级 PID 为什么外环输出是内环的期望?(和我之前对串级PID的总结一样)
查看>>
APM/Pixhawk飞行日志分析入门(苍穹四轴)
查看>>
我刚刚才完全清楚GPS模块的那根杆子是怎么固定安装好的
查看>>
去github里面找找也没有别人无人机+SLAM的工程
查看>>
PX4与ROS关系以及仿真控制(键盘控制无人机)
查看>>
我对无人机重心高度的理解
查看>>
现在明白为什么无名博客里好几篇文章在讲传感器的滞后
查看>>
无人机不装脚架的好处就是降落时会比较稳,不怕倾斜侧翻。
查看>>
实际我看Pixhawk定高模式其实也是飞得很稳,飘得也不厉害
查看>>