java 堆 排序学习
/**
* <html>
* <body>
* <P> Copyright 1994 JsonInternational</p>
* <p> All rights reserved. - https://github.com/Jasonandy/Java-Core-Advanced </p>
* <p> Created by Jason</p>
* </body>
* </html>
*/
package cn.ucaner.datastructure.heap; /**
* @Package:cn.ucaner.datastructure.heap
* @ClassName:MinHeap
* @Description: <p> 最小堆 :完全二叉树,能方便地从中取出最小/大元素 </p>
* 堆的构建
* 堆的打印(前序遍历的应用)
* 堆的插入(插入到堆尾,再自下向上调整为最小堆)
* 堆的删除(删除堆顶元素并用堆尾元素添补,再自上向下调整为最小堆)
* 堆排序(时间复杂度:O(nlgn),空间复杂度O(1),不稳定):升序排序一般用最大堆
* @Author: -
* @CreatTime:2018年6月8日 上午10:48:46
* @Modify By:
* @ModifyTime: 2018年6月8日
* @Modify marker:
* @version V1.0
*/
public class MinHeap { /**
* 将所有元素以完全二叉树的形式存入数组
*/
private int[] heap; /**
* 堆中元素的个数
*/
private int size; /**
* MinHeap. 构造函数 - 构建一个大小为size的最小堆
* @param maxSize
*/
public MinHeap(int maxSize) {
heap = new int[maxSize];
} /**
* MinHeap. 构造函数
* @param arr 基于数组构造最小堆
* @param maxSize
*/
public MinHeap(int[] arr, int maxSize) {
heap = new int[maxSize > arr.length ? maxSize : arr.length];
System.arraycopy(arr, 0, heap, 0, arr.length);
size = arr.length; int pos = (size - 2) / 2; // 最初调整位置:最后的分支节点(最后叶节点的父亲)
while (pos >= 0) { //依次调整每个分支节点
shiftDown(pos, size - 1);
pos--;
}
} /**
* @Description: 自上向下调整为最小堆(从不是最小堆调整为最小堆),调整的前提是其左子树与右子树均为最小堆
* @param start
* @param end void
* @Autor: jason - jasonandy@hotmail.com
*/
private void shiftDown(int start, int end) {
int i = start; // 起始调整位置,分支节点
int j = 2 * start + 1; // 该分支节点的子节点
int temp = heap[i];
while (j <= end) { // 迭代条件:子节点不能超出end(范围)
if (j < end) {
j = heap[j] > heap[j + 1] ? j + 1 : j; // 选择两孩子中较小的那个
}
if (temp < heap[j]) { // 较小的孩子大于父亲,不做任何处理
break;
} else { // 否则,替换父节点的值
heap[i] = heap[j];
i = j;
j = 2 * j + 1;
}
}
heap[i] = temp; // 一步到位
} /**
* @Description: 自下向上调整为最小堆(原来已是最小堆,添加元素后,确保其还是最小堆)
* @Autor:jason - jasonandy@hotmail.com
*/
private void shiftUp(int start) {
int j = start;
int i = (j - 1) / 2; // 起始调整位置,分支节点
int temp = heap[j];
while (j > 0) { // 迭代条件:子节点必须不为根
if (temp >= heap[i]) { //原已是最小堆,所以只需比较这个子女与父亲的关系即可
break;
} else {
heap[j] = heap[i];
j = i;
i = (j - 1) / 2;
}
}
heap[j] = temp; // 一步到位
} /**
* @Description: 向最小堆插入元素(总是插入到最小堆的最后)
* @param data
* @Autor: jason - jasonandy@hotmail.com
*/
public void insert(int data){
if (size < heap.length) {
heap[size++] = data; // 插入堆尾
shiftUp(size-1); // 自下而上调整
}
} /**
* @Description:删除堆顶元素,以堆的最后一个元素填充
* @Autor: jason - jasonandy@hotmail.com
*/
public void remove() {
if (size > 0) {
heap[0] = heap[size-1]; // 删除堆顶元素,并将堆尾元素回填到堆顶
size --; // 堆大小减一
shiftDown(0, size-1); // 自上向下调整为最小堆
}
} /**
* @Description: 堆排序:每次将最小元素交换到最后
* @Autor: jason - jasonandy@hotmail.com
*/
public void sort(){
for (int i = size - 1; i >= 0; i--) {
int temp = heap[0];
heap[0] = heap[i];
heap[i] = temp; shiftDown(0, i-1);
} for (int i = size-1; i >= 0; i--) {
System.out.print(heap[i] + " ");
}
} /**
* @Description: 打印根为 i 的最小堆
* @param i
* @Autor: Jason - jasonandy@hotmail.com
*/
public void printMinHeap(int i) {
if (size > i) {
System.out.print(heap[i]);
if (2 * i + 1 < size || 2 * i + 2 < size) {
System.out.print("(");
printMinHeap(2 * i + 1);
System.out.print(",");
printMinHeap(2 * i + 2);
System.out.print(")");
}
}
}
}
java 堆 排序学习的更多相关文章
- 从几个sample来学习JAVA堆、方法区、JAVA栈和本地方法栈
最近在看<深入理解Java虚拟机>,书中给了几个例子,比较好的说明了几种OOM(OutOfMemory)产生的过程,大部分的程序员在写程序时不会太关注Java运行时数据区域的结构: 感觉有 ...
- 从sample来学习Java堆(转)
1)Java堆 所有对象的实例分配都在Java堆上分配内存,堆大小由-Xmx和-Xms来调节,sample如下所示: public class HeapOOM { static class OOMOb ...
- JVM学习--(八)java堆分析
上一节介绍了针对JVM的监控工具,包括JPS可以查看当前所有的java进程,jstack查看线程栈可以帮助你分析是否有死锁等情况,jmap可以导出java堆文件在MAT工具上进行分析等等.这些工具都非 ...
- 《深入理解java虚拟机》学习笔记之编译优化技术
郑重声明:本片博客是学习<深入理解Java虚拟机>一书所记录的笔记,内容基本为书中知识. Java程序员有一个共识,以编译方式执行本地代码比解释方式更快,之所以有这样的共识,除去虚拟机解释 ...
- 《深入理解Java虚拟机》学习笔记
<深入理解Java虚拟机>学习笔记 一.走近Java JDK(Java Development Kit):包含Java程序设计语言,Java虚拟机,JavaAPI,是用于支持 Java 程 ...
- Java虚拟机(JVM) - 学习总结(全)
深入理解java虚拟机---学习总结: 1.Java内存区域 1.1 java运行时数据区 Java 虚拟机所管理的内存如下图所示,基于JDK1.6. 基于jdk1.8画的JVM的内存模型 (1) 程 ...
- 《深入理解 java虚拟机》学习笔记
java内存区域详解 以下内容参考自<深入理解 java虚拟机 JVM高级特性与最佳实践>,其中图片大多取自网络与本书,以供学习和参考.
- Java程序员学习之路
1. Java语言基础 谈到Java语 言基础学习的书籍,大家肯定会推荐Bruce Eckel的<Thinking in Java>.它是一本写的相当深刻的技术书籍,Java语言基础部分基 ...
- Java虚拟机JVM学习07 类的卸载机制
Java虚拟机JVM学习07 类的卸载机制 类的生命周期 当Sample类被加载.连接和初始化后,它的生命周期就开始了. 当代表Sample类的Class对象不再被引用,即不可触及时,Class对象就 ...
随机推荐
- js constructor typeOf 区别
constructor 属性返回对创建此对象的数组函数的引用. 例如:const obj = {a: 1} console.log(obj.constructor) // funct ...
- Tcl数学运算
expr 数学表达式 Tcl支持的数学操作符(优先级按照从高到低): -一元负号 +一元正号 ~按位取反 !逻辑非 *乘 /除 %取余 +加号 -减号 <<左移位 >>右移位 ...
- intellij ide 集成cmder
1.环境变量配置: https://github.com/cmderdev/cmder/wiki/Setting-up-Environment-Variables 2.intellijide的配置:h ...
- idea在docker环境,调试spring boot程序
允许docker被远程访问 见:https://www.cnblogs.com/wintersoft/p/10921396.html 教程见:https://spring.io/guides/gs/s ...
- Java_jdbc 基础笔记之九 数据库连接 (查询Customer对象的方法)
/** * * 写一个查询Customer对象的方法 * */ public Customer getCustomer(String sql, Object... args) { Customer c ...
- 运维笔记--ubuntu安装指定版本的RabbitMQ
场景描述: 日常开发or生产环境经常会需要安装指定版本的软件,出于和其他软件的配合兼容性,以及稳定性的考虑. 现在我们的需求是安装指定版本的RabbitMQ,版本号: 操作步骤: 注意事项: 异常处理 ...
- webconfig 配置 分离
https://blog.csdn.net/zhifeiya/article/details/38828711 如标题,如何把 asp.net webconfig的appSettings分离到单独文件 ...
- Sublime用正则表达式进行逗号分隔实现列的替换
eg: ([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*).* 这是取前面10列,后面的不管 ...
- 【翻译】Flink Table Api & SQL —— 数据类型
本文翻译自官网:https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/table/types.html Flink Table ...
- 采用EasyDSS视频点播服务器搭建企业私有化的音视频多媒体、短视频、视频服务网站与管理后台
最近有越来越多的用户咨询关于视频点播的功能,主要需求就是集中于如何搭建专属的私有化视频点播平台: 实现的功能类似于,对应自身拥有的视频文件,需要发布到一个网站,其他用户都可以实现点播观看. 针对于类似 ...