java 二叉堆_二叉堆的介绍和Java实现
一、堆和二叉堆
堆,英文名称Heap,所谓二叉堆(也有直接称二叉堆为堆的),本质上是一个完全二叉树,前面也提到过,如果树接近于完全二叉树或者满二叉树,采用顺序存储代价会小一点,因此常见的二叉堆均是顺序实现的。
按照排列的顺序可以分为最大堆和最小堆,最大堆的特征是父节点一定大于(依据情况判断是大于等于还是严格大于,数据结构归根到底还是用来使用的)子节点的数据。同样,有最大堆就会有最小堆,最小堆的 父节点数据小于其子节点的数据,因此根节点的数据是最小的。下面左图是一个最小堆,右图是一个最大堆。
二、二叉堆的插入和删除
详细来看,二叉堆的主要操作就是插入和删除。以一个最小堆为例,我们详细介绍插入和删除的操作。
以上是一个最小二叉堆的插入过程,比如我们要插入一个节点0,但是他的数据小于它父节点的数据,因此它和它父节点交换数据,如上面的第三张图所示。然后继续判断,它仍连续两次小于父节点数据,因此再交换两次数据,形成最终的那张图,就是插入后的最小二叉堆。
一般来说,二叉堆的删除主要是指删除堆顶的数据,即根节点的数据。我们使用之前插入后得到的二叉堆作为目标,我们对其进行删除操作,假设再次删除节点0,然后将数组中最后一位(节点3)填充进去;然后和子节点的数据进行比较,这时候我们必须要从左右子节点中选出更小的那一个作比较,显然是左节点1较小;如果该节点数据大于子节点(较小的那个)的数据,那就和子节点数据进行交换,直至符合条件;
而查找性的删除则比较复杂,从堆尾补充进删除位置的新数据首先要和父节点的数据进行比较,如果小于,就把该节点一直往上交换,直至停止。但本实例中该节点是根节点,不存在父节点,因此就没有这一步;然后按照上面那一段描述与子节点进行比较,交换。
三、二叉堆的Java实现
成员域由ArrayList data代表堆中的数据,因为数组无法适配泛型。
插入
public voidinsert(Y y)
{
data.add(y);int index = data.size() - 1;while(((index + 1) / 2 - 1) >= 0 && data.get(index).compareTo(data.get((index + 1) / 2 - 1)) < 0)
{
Y temp= data.get((index + 1) / 2 - 1);
data.set((index+ 1) / 2 - 1, y);
data.set(index,temp);
index= (index + 1) / 2 - 1;
}
}
删除
public booleandelete(Y y)
{if(data.size() == 0)return false;else if (data.indexOf(y) == -1)return false;else{int index =data.indexOf(y);
data.set(index, data.get(data.size()- 1));
data.remove(data.size()- 1);
/* parent */while(((index + 1) / 2 - 1) >= 0 && data.get(index).compareTo(data.get((index + 1) / 2 - 1)) < 0)
{
Y temp= data.get((index + 1) / 2 - 1);
data.set((index+ 1) / 2 - 1, data.get(index));
data.set(index,temp);
index= (index + 1) / 2 - 1;
}/*child*/
while((2 * index + 1) <= data.size()-1)
{if ((2 * index + 2) <= data.size()-1) //如果该节点左右子树均存在
{int cmp = data.get(2 * index + 1).compareTo(data.get(2 * index + 2)); //比较子树的大小if (cmp > 0) //左子树大于右子树,则交换右子树
{if (data.get(index * 2 + 2) .compareTo(data.get(index)) < 0) {
Y temp= data.get(index * 2 + 2);
data.set(index* 2 + 2, data.get(index));
data.set(index, temp);
index= index * 2 + 2;
}
else
break; }else //右子树大于左子树,则交换左子树{if(data.get(index * 2 + 1) .compareTo(data.get(index)) < 0) {
Y temp= data.get(index * 2 + 1);
data.set(index* 2 + 1, data.get(index));
data.set(index, temp);
index= index * 2 + 1;
}
else
break; }
}else if ((2 * index + 2) > data.size()-1) //只存在左子树
{if(data.get(index * 2 + 1) .compareTo(data.get(index)) < 0) { //判断左子树和节点大小
Y temp= data.get(index * 2 + 1);
data.set(index* 2 + 1, data.get(index));
data.set(index, temp);
index= index * 2 + 1;
}
else
break;
}
}return true;
}
}
测试代码1
以此堆为例,插入0后删除0
Heap h = new Heap<>();
Integer [] i= {1,2,5,3,4,6,7};for (int j = 0; j < i.length; j++)
{
h.insert(i[j]);
}
h.traverse();
System.out.println();
h.insert(0);
h.traverse();
System.out.println();
h.delete(0);
h.traverse();
Test 1
结果1:
————————————————————————————————————————————————————————
测试代码2
Heap h = new Heap<>();
Integer [] i= {10,20,40,30,60,80,110,50,70,90,100};for (int j = 0; j < i.length; j++)
{
h.insert(i[j]);
}
h.traverse();
System.out.println();
h.insert(0);
h.traverse();
System.out.println();
h.delete(0);
h.traverse();
Test 2
结果2:
java 二叉堆_二叉堆的介绍和Java实现相关推荐
- java学习 类变量 类方法_这篇文章主要介绍了JAVA类变量及类方法代码实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下类变量(...
这篇文章主要介绍了JAVA类变量及类方法代码实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 类变量(static) 类变量是该类的所有对象共 ...
- java 二叉堆_二叉堆(三)之 Java的实现
概要 前面分别通过C和C++实现了二叉堆,本章给出二叉堆的Java版本.还是那句话,它们的原理一样,择其一了解即可. 二叉堆的介绍 二叉堆是完全二元树或者是近似完全二元树,按照数据的排列方式可以分为两 ...
- aix系统java堆_浅谈AIX环境下的Java性能调优
1.什么是Java Java 是一种面向对象的编程语言.它以 C++ 为模型,被设计成小的.简单的.在源和二进制级别跨平台的可移植的语言,Java 程序(applets 和应用程序)可以运行于任何已经 ...
- c++ 二维数组_二维数组的声明2019_04_18
-------------[感谢小郡提供的图片] [广告位招租] ---------------------------------------------------------------- -- ...
- 生成有时间限制的二维码_二维码竟有被用完的一天!看到截止日期后,网友:虚惊一场...
生活在现如今这样一个智能化的时代中,二维码已经逐渐成为了人们日常生活中必不可少的存在.出门骑共享单车要扫码.购物买东西要出示微信.支付宝付款码.聊天加好友同样也是要用到二维码,可以说现在的生活中已经无 ...
- python定义二维数组_二维数组的定义、初始化和输出,C语言二维数组详解
本节学习二维数组.二维数组与一维数组相似,但是用法上要比一维数组复杂一点.后面的编程中,二维数组用得很少,因为二维数组的本质就是一维数组,只不过形式上是二维的.能用二维数组解决的问题用一维数组也能解决 ...
- java排序算法大全_各种排序算法的分析及java实现
排序一直以来都是让我很头疼的事,以前上<数据结构>打酱油去了,整个学期下来才勉强能写出个冒泡排序.由于要找工作了,也知道排序算法的重要性(据说是面试必问的知识点),所以又花了点时间重新研究 ...
- java实现apriori算法_各种排序算法的分析及java实现(一)
阅读本文约需要7分钟 大家好,我是你们的导师,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许老师休息一下哈).上次老师跟大家分享了下用Navicat for Mysql导入.sql文件的 ...
- java高深技术总结_一名25K以上的高薪Java程序员总结出的技术以及学习技能
原标题:一名25K以上的高薪Java程序员总结出的技术以及学习技能 总所周知,Java是目前使用最为广泛的网络编程语言之一. 它具有简单,面向对象,稳定,与平台无关,解释型,多线程,动态等特点. 一般 ...
最新文章
- 单个Transformer完成信息检索,谷歌用可微搜索索引打败双编码器模型
- SAP CAR integration with S/4 HANA
- lanmp环境的搭建
- 解码大脑:改善BCI稳定性
- jvm配置参数,查看大对象直接分配到老年代
- c访问excel 密码 api_管理EXCEL的5种服务使用渠道
- 现代企业三大目标才是核心
- Ubuntu下查看cuda版本的两种方法
- leetcode69 x的平方根
- 关于指针赋初值为NULL的问题
- 双系统双硬盘安装(win7 64位+Ubuntu18.04)(固态硬盘+机械硬盘1T)小结
- 关于容斥定理、勾股数公式、排列组合置换公式的总结
- win10使用FFmpeg录屏/录音
- 误删除系统libselinux.so.1之后
- 中职 计算机专业,中职计算机专业发展新思维
- “HIMO CUBE”全新亮相ADM展,海马体照相馆获原创品牌创新奖
- 程式中檢查是否潤年的新方法
- Maven的settings.xml的详细配置
- 前端跳转失败,例如返回按钮,js跳转失败的踩坑原因之一
- L2-012 关于堆的判断 - 小顶堆(详解)
热门文章
- 联想小新Air14使用傲梅分区助手进行硬盘克隆出现的问题,克隆完显示RAW格式解决方案,win10家庭版硬盘BitLocker上锁解锁方法
- Java之第一行代码
- 计算机系统结构之重要知识点总结1
- mysql 127.0.0.13306_MySQL 问题解决
- ThinkPHP 开发XXXXX后台
- SpringBoot实现代码生成器——基于SpringBoot和Vue的后台管理系统项目系列博客(十)
- sicily1198
- spring + mybatis + c3p0 整合(配置篇)
- 文件,文件夹对比工具(Beyond Compare)
- 检信智能群体性运动多通道心电监测系统