打印二叉堆(Java实现)
打印二叉堆:利用层级关系
我这里是先将堆排序,然后在sort里执行了打印堆的方法printAsTree()
public class MaxHeap<T extends Comparable<? super T>> {
private T[] data;
private int size;
private int capacity; public MaxHeap(int capacity) {
this.capacity = capacity;
this.size = 0;
this.data = (T[]) new Comparable[capacity + 1];
} public MaxHeap(T[] arr) {//heapify,数组建堆
capacity = arr.length;
data = (T[]) new Comparable[capacity + 1];
System.arraycopy(arr, 0, data, 1, arr.length);
size = arr.length;
for (int i = size / 2; i >= 1; i--) {
shiftDown(i);
}
} public int size() {
return this.size;
} public int getCapacity() {
return this.capacity;
} public boolean isEmpty() {
return size == 0;
} public T seekMax() {
return data[1];
} public void swap(int i, int j) {
if (i != j) {
T temp = data[i];
data[i] = data[j];
data[j] = temp;
}
} public void insert(T item) {
size++;
data[size] = item;
shiftUp(size);
} public T popMax() {
swap(1, size--);
shiftDown(1);
return data[size + 1];
} public void shiftUp(int child) {
while (child > 1 && data[child].compareTo(data[child / 2]) > 0) {
swap(child, child / 2);
child /= 2;
}
} /**
* @param a data数组中某个元素的下角标
* @param b data数组中某个元素的下角标
* @return 哪个元素大就返回哪个的下角标
*/
private int max(int a, int b) {
if (data[a].compareTo(data[b]) < 0) {//如果data[b]大
return b;//返回b
} else {//如果data[a]大
return a;//返回a
}
} /**
* @param a data数组中某个元素的下角标
* @param b data数组中某个元素的下角标
* @param c data数组中某个元素的下角标
* @return 哪个元素大就返回哪个的下角标
*/
private int max(int a, int b, int c) {
int biggest = max(a, b);
biggest = max(biggest, c);
return biggest;
} public void shiftDown(int father) {
while (true) {
int lchild = father * 2;
int rchild = father * 2 + 1;
int newFather = father;//这里赋不赋值无所谓,如果把下面这个return改成break,那就必须赋值了 if (lchild > size) {//如果没有左、右孩子
return;
} else if (rchild > size) {//如果没有右孩子
newFather = max(father, lchild);
} else {//如果有左、右孩子
newFather = max(father, lchild, rchild);
} if (newFather == father) {//如果原父结点就是三者最大,则不用继续整理堆了
return;
} else {//父节点不是最大,则把大的孩子交换上来,然后继续往下堆调整,直到满足大根堆为止
swap(newFather, father);
father = newFather;//相当于继续shiftDown(newFather)。假如newFather原来是father的左孩子,那就相当于shiftDown(2*father)
}
}
} public static <T extends Comparable<? super T>> void sort(T[] arr) {
int len = arr.length;
MaxHeap<T> maxHeap = new MaxHeap<>(arr);
maxHeap.printAsTree();
for (int i = len - 1; i >= 0; i--) {
arr[i] = maxHeap.popMax();
}
} public static void printArr(Object[] arr) {
for (Object o : arr) {
System.out.print(o);
System.out.print("\t");
}
System.out.println();
} public void printSpace(int n) {//打印n个空格(在这里用‘\t’来代替)
for (int i = 0; i < n; i++) {
System.out.printf("%3s", "");
}
} public void printAsTree() {
int lineNum = 1;//首先遍历第一行
int lines = (int) (Math.log(size) / Math.log(2)) + 1;//lines是堆的层数
int spaceNum = (int) (Math.pow(2, lines) - 1);
for (int i = 1; i <= size; ) { //因为在[1...size]左闭右闭区间存数据,data[0]不存数据 //每层都是打印这个区间[2^(层数-1) ... (2^层数)-1]。如果堆里的数不够(2^层数)-1个,那就打印到size。所以取min((2^层数)-1,size).
for (int j = (int) Math.pow(2, lineNum - 1); j <= Math.min(size, (int) Math.pow(2, lineNum) - 1); j++) {
printSpace(spaceNum); //打印spaceNum个空格
System.out.printf("%3s", data[j]);//打印数据
System.out.printf("%3s", "");//图片中绿色方框
printSpace(spaceNum);//打印spaceNum个空格
i++;//每打印一个元素就 + 1
}
lineNum++;
spaceNum = spaceNum / 2;
System.out.println();
}
} public static void main(String args[]) {
Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6, 1, 3, 6, 1, 1};
sort(arr);
}
}
执行结果:
打印二叉堆(Java实现)的更多相关文章
- 优先队列的二叉堆Java实现
package practice; import edu.princeton.cs.algs4.StdRandom; public class TestMain { public static voi ...
- 二叉堆(一)之 图文解析 和 C语言的实现
概要 本章介绍二叉堆,二叉堆就是通常我们所说的数据结构中"堆"中的一种.和以往一样,本文会先对二叉堆的理论知识进行简单介绍,然后给出C语言的实现.后续再分别给出C++和Java版本 ...
- 二叉堆(二)之 C++的实现
概要 上一章介绍了堆和二叉堆的基本概念,并通过C语言实现了二叉堆.本章是二叉堆的C++实现. 目录1. 二叉堆的介绍2. 二叉堆的图文解析3. 二叉堆的C++实现(完整源码)4. 二叉堆的C++测试程 ...
- 二叉堆的实现(数组)——c++
二叉堆的介绍 二叉堆是完全二元树或者是近似完全二元树,按照数据的排列方式可以分为两种:最大堆和最小堆.最大堆:父结点的键值总是大于或等于任何一个子节点的键值:最小堆:父结点的键值总是小于或等于任何一个 ...
- PriorityBlockingQueue优先队列的二叉堆实现
转载请注明原创地址http://www.cnblogs.com/dongxiao-yang/p/6293807.html java.util.concurrent.PriorityBlockingQu ...
- 二叉堆(三)之 Java的实现
概要 前面分别通过C和C++实现了二叉堆,本章给出二叉堆的Java版本.还是那句话,它们的原理一样,择其一了解即可. 目录1. 二叉堆的介绍2. 二叉堆的图文解析3. 二叉堆的Java实现(完整源码) ...
- 纯数据结构Java实现(6/11)(二叉堆&优先队列)
堆其实也是树结构(或者说基于树结构),一般可以用堆实现优先队列. 二叉堆 堆可以用于实现其他高层数据结构,比如优先队列 而要实现一个堆,可以借助二叉树,其实现称为: 二叉堆 (使用二叉树表示的堆). ...
- 二叉堆的构建(Java)
package com.rao.linkList; /** * @author Srao * @className BinaryHeap * @date 2019/12/3 14:14 * @pack ...
- 二叉堆的介绍和Java实现
一.堆和二叉堆 堆,英文名称Heap,所谓二叉堆(也有直接称二叉堆为堆的),本质上是一个完全二叉树,前面也提到过,如果树接近于完全二叉树或者满二叉树,采用顺序存储代价会小一点,因此常见的二叉堆均是顺序 ...
随机推荐
- 在JDBC中使用Java8的日期LocalDate、LocalDateTime
在实体Entity里面,可以使用java.sql.Date.java.sql.Timestamp.java.util.Date来映射到数据库的date.timestamp.datetime等字段 但是 ...
- JS分号 惹的坑
JS中会自动清除句子和句子之间的空格以及tab缩进, 这样就可以允许用户编写的代码更加随性和更加可读, 在该行代码解析的时候如果该行代码可以解析, 就会在该行代码最后自动填写分号,如果该行代码无法解析 ...
- mysql常用基础操作语法(十二)~~常用数值函数【命令行模式】
数值函数是常用函数之一,也是学习mysql必会的,常用的有如下一些: 1.ceil:返回大于某个数的最小整数值: 2.floor:和上一个相反,返回小于某个数的最大整数值: 3.round:返回某个数 ...
- 关于SSDT
百度上比较好的解释是:SSDT的全称是System Services Descriptor Table,系统服务描述符表.这个表就是一个把ring3的Win32 API和ring0的内核API联系起来 ...
- Extjs 4.0 Tab页
1.JSON代码 Ext.MyTabs=Ext.extend(Ext.TabPanel ,{ xtype:"tabpanel", activeTab:2, width:694, h ...
- Java Web项目报错总结
Java Web项目报错总结 1.java.lang.IllegalStateException java.lang.IllegalStateException Caused by:java.lang ...
- 图像处理------Canny边缘检测
一:历史 Canny边缘检测算法是1986年有John F. Canny开发出来一种基于图像梯度计算的边缘 检测算法,同时Canny本人对计算图像边缘提取学科的发展也是做出了很多的贡献.尽 管至今已经 ...
- Vxworks下的SATA提速
1. ATA接口的三种数据传输方式 (1)PIO(Programmable Input-Output)传输,可以分为PIO寄存器传输和PIO数据传输.PIO寄存器传输主要用于对ATA设备中 ...
- freemarker.template.TemplateException:Macro has no such argument:params
1.错误描述 freemarker.template.TemplateException:Macro mainSelect has no such argument:params 2.错误原因 在宏定 ...
- Flex上传文件报“Error #2038”
1.错误描述 ioerror: [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 t ...