一、堆和二叉堆

堆,英文名称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实现相关推荐

  1. java学习 类变量 类方法_这篇文章主要介绍了JAVA类变量及类方法代码实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下类变量(...

    这篇文章主要介绍了JAVA类变量及类方法代码实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 类变量(static) 类变量是该类的所有对象共 ...

  2. java 二叉堆_二叉堆(三)之 Java的实现

    概要 前面分别通过C和C++实现了二叉堆,本章给出二叉堆的Java版本.还是那句话,它们的原理一样,择其一了解即可. 二叉堆的介绍 二叉堆是完全二元树或者是近似完全二元树,按照数据的排列方式可以分为两 ...

  3. aix系统java堆_浅谈AIX环境下的Java性能调优

    1.什么是Java Java 是一种面向对象的编程语言.它以 C++ 为模型,被设计成小的.简单的.在源和二进制级别跨平台的可移植的语言,Java 程序(applets 和应用程序)可以运行于任何已经 ...

  4. c++ 二维数组_二维数组的声明2019_04_18

    -------------[感谢小郡提供的图片] [广告位招租] ---------------------------------------------------------------- -- ...

  5. 生成有时间限制的二维码_二维码竟有被用完的一天!看到截止日期后,网友:虚惊一场...

    生活在现如今这样一个智能化的时代中,二维码已经逐渐成为了人们日常生活中必不可少的存在.出门骑共享单车要扫码.购物买东西要出示微信.支付宝付款码.聊天加好友同样也是要用到二维码,可以说现在的生活中已经无 ...

  6. python定义二维数组_二维数组的定义、初始化和输出,C语言二维数组详解

    本节学习二维数组.二维数组与一维数组相似,但是用法上要比一维数组复杂一点.后面的编程中,二维数组用得很少,因为二维数组的本质就是一维数组,只不过形式上是二维的.能用二维数组解决的问题用一维数组也能解决 ...

  7. java排序算法大全_各种排序算法的分析及java实现

    排序一直以来都是让我很头疼的事,以前上<数据结构>打酱油去了,整个学期下来才勉强能写出个冒泡排序.由于要找工作了,也知道排序算法的重要性(据说是面试必问的知识点),所以又花了点时间重新研究 ...

  8. java实现apriori算法_各种排序算法的分析及java实现(一)

    阅读本文约需要7分钟 大家好,我是你们的导师,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许老师休息一下哈).上次老师跟大家分享了下用Navicat for Mysql导入.sql文件的 ...

  9. java高深技术总结_一名25K以上的高薪Java程序员总结出的技术以及学习技能

    原标题:一名25K以上的高薪Java程序员总结出的技术以及学习技能 总所周知,Java是目前使用最为广泛的网络编程语言之一. 它具有简单,面向对象,稳定,与平台无关,解释型,多线程,动态等特点. 一般 ...

最新文章

  1. 单个Transformer完成信息检索,谷歌用可微搜索索引打败双编码器模型
  2. SAP CAR integration with S/4 HANA
  3. lanmp环境的搭建
  4. 解码大脑:改善BCI稳定性
  5. jvm配置参数,查看大对象直接分配到老年代
  6. c访问excel 密码 api_管理EXCEL的5种服务使用渠道
  7. 现代企业三大目标才是核心
  8. Ubuntu下查看cuda版本的两种方法
  9. leetcode69 x的平方根
  10. 关于指针赋初值为NULL的问题
  11. 双系统双硬盘安装(win7 64位+Ubuntu18.04)(固态硬盘+机械硬盘1T)小结
  12. 关于容斥定理、勾股数公式、排列组合置换公式的总结
  13. win10使用FFmpeg录屏/录音
  14. 误删除系统libselinux.so.1之后
  15. 中职 计算机专业,中职计算机专业发展新思维
  16. “HIMO CUBE”全新亮相ADM展,海马体照相馆获原创品牌创新奖
  17. 程式中檢查是否潤年的新方法
  18. Maven的settings.xml的详细配置
  19. 前端跳转失败,例如返回按钮,js跳转失败的踩坑原因之一
  20. L2-012 关于堆的判断 - 小顶堆(详解)

热门文章

  1. 联想小新Air14使用傲梅分区助手进行硬盘克隆出现的问题,克隆完显示RAW格式解决方案,win10家庭版硬盘BitLocker上锁解锁方法
  2. Java之第一行代码
  3. 计算机系统结构之重要知识点总结1
  4. mysql 127.0.0.13306_MySQL 问题解决
  5. ThinkPHP 开发XXXXX后台
  6. SpringBoot实现代码生成器——基于SpringBoot和Vue的后台管理系统项目系列博客(十)
  7. sicily1198
  8. spring + mybatis + c3p0 整合(配置篇)
  9. 文件,文件夹对比工具(Beyond Compare)
  10. 检信智能群体性运动多通道心电监测系统