数据结构Java版之堆&堆排序(九)
堆分为大顶堆,和小顶堆。 什么是堆? 堆可以看成是一棵二叉树,二叉树的元素是一个数组不断的从左到右轮训放置。如果是大顶堆,则大的数放上面一层,小的数放下面一层。上一层的数,一定大于下一层的数。小顶堆则相反。
那么,如何实现一个大顶堆?这里我用一个链表来实现。
实现堆很简单,只要牢记他的原理就行了。
添加新元素:添加至数组末尾。然后对这个末尾节点不断的向上层冒泡。直到找到一个合适的节点放置。
删除元素:从数组末尾取出一个元素对当前要删除的元素进行覆盖,后删除末尾的元素。然后从当前节点不断的向下冒泡。就能找到一个合适的位置进行放置。
上层元素和下层元素之间的关系:上层元素(索引为:index )和下层元素索引存在 2 * index + 1(左孩子节点) 2 * index + 2(右孩子节点)的关系。
实现源码:
package heap; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import org.junit.Test; public class Heap {
private List<Integer> heapArray;
public Heap() {
super();
this.heapArray = new ArrayList();
}
//添加元素进堆
public void Push(Integer x) {
heapArray.add(x);
trickleUp(heapArray.size()-1);
}
//删除元素
public void Pop() {
heapArray.set(0, heapArray.get(heapArray.size()-1));
heapArray.remove(heapArray.size()-1);
trickleDown(0);
}
//取出根数据
public Integer Top() {
return heapArray.get(0);
}
//判断是否为空
public boolean isEmpty() {
if(Top() == null) {
return true;
}
return false;
}
//向上渗透
public void trickleUp(int index) {
int parent = (index-1) / 2;
Integer bottom = heapArray.get(index);
while(index > 0 && heapArray.get(parent) < bottom) {
heapArray.set(index, heapArray.get(parent));
index = parent;
parent = (parent - 1) / 2;
}
heapArray.set(index, bottom);
}
//向下渗透
public void trickleDown(int index) {
Integer top = heapArray.get(0);
int lagerChild;
while(index < heapArray.size()/2) {
int leftChild = index * 2 + 1;
int rightChild = index * 2 + 2;
if(rightChild < heapArray.size() && heapArray.get(leftChild) < heapArray.get(rightChild)) {
lagerChild = rightChild;
}else {
lagerChild = leftChild;
}
if(top >= heapArray.get(lagerChild)) {
break;
}
heapArray.set(index, heapArray.get(lagerChild));
index = lagerChild;
}
heapArray.set(index, top);
}
}
测试程序:
@Test
public void fun() {
Heap p = new Heap();
p.Push(20);
p.Push(30);
p.Push(15);
System.out.println(p.Top());
p.Push(90);
p.Push(35);
System.out.println(p.Top());
p.Pop();
System.out.println(p.Top());
}
测试结果:
30
90
35
堆排序:
堆排序非常简单,利用大顶堆的顶一定是堆元素里面的最大值。那么我们就可以将一系列数据存进去,再不断的取出顶元素。取除的元素就是一个排好序的元素。
源码:
public static void main(String[] args) {
Heap h = new Heap();
h.Push(2);
h.Push(1);
h.Push(4);
h.Push(6);
System.out.println(h.Top());
h.Pop();
System.out.println(h.Top());
h.Pop();
System.out.println(h.Top());
h.Pop();
System.out.println(h.Top());
}
结果:
6
4
2
1
至此,堆排序就已经做好了。
数据结构Java版之堆&堆排序(九)的更多相关文章
- 数据结构Java版之交换算法(一)
交换的本质是拷贝,其中拷贝包括两种方式.值拷贝和指针拷贝,在java中没有指针,为此,我们可以理解为地址拷贝,在我看来,指针就是地址. 1.传值方式示例: 由上述示例可得,传值,不能起到交换的作用,原 ...
- 数据结构Java版之广度优先图(十三)
广度优先,则是用的队列,将每一层的节点先存入队列中去,后依次取出队列中的节点,显示与当前节点存在边,但是未被访问过的节点,也就是下一层与之相联系的节点,再将这些节点存入队列.经过层层迭代,就可以完全遍 ...
- 数据结构Java版之深度优先-图(十二)
这里用深度优先遍历存在矩阵里面的图. 深度优先利用的是栈的FIFO特性.为此遍历到底后,可以找到最相邻的节点继续遍历.实现深度优先,还需要在节点加上一个访问标识,来确定该节点是否已经被访问过了. 源码 ...
- 数据结构Java版之邻接矩阵实现图(十一)
邻接矩阵实现图,是用一个矩阵,把矩阵下标作为一个顶点,如果顶点与顶点之间有边.那么在矩阵对应的点上把值设为 1 .(默认是0) package mygraph; import java.util.Li ...
- 数据结构Java版之邻接表实现图(十)
邻接表实现图,实际上是在一个数组里面存放链表,链表存放的是连接当前节点的其他节点. package mygraph; import java.util.ArrayList; import java.u ...
- 数据结构Java版之遍历二叉树(六)
二叉树是我们在程序中用的最多的一种树(个人观点).最简单的一个二叉树是由一个根节点,两个子节点(一左一右成左右孩子节点)组成.二叉树是数组和链表的结合,即包含了数组的快速查找优点,又包含了链表的快速添 ...
- 数据结构Java版之递归与迭代算法(五)
递归的概念很简单,就是自己调用自己. 而迭代,则是通过修改初始化数据,得到中间结果,然后不断的对中间结果进行修改,而得到最终结果.简单来说迭代就是循环. 在此,我们用一个比较经典的Fibonacci数 ...
- 数据结构Java版之基数排序(四)
基数排序: 基数排序分为两种:第一种是LSD ,从最低位开始排序, 第二种是 MSD 从最高位开始排.这里介绍第一种LSD排序算法. 首先,我们先了解什么是基数.基数是根据具体的排序情况而定的,比如我 ...
- 数据结构Java版之红黑树(八)
红黑树是一种自动平衡的二叉查找树,因为存在红黑规则,所以有效的防止了二叉树退化成了链表,且查找和删除的速度都很快,时间复杂度为log(n). 什么是红黑规则? 1.根节点必须是黑色的. 2.节点颜色要 ...
随机推荐
- Git使用整理
[本文由水木桶首发于博客园,原文地址:https://www.cnblogs.com/shuimutong/p/11404664.html,未接允许,严禁转载] 背景 很久之前使用的是svn,直接在E ...
- element-ui DatePicker 日期格式处理
1.使用DatePicker 日期选择器得到的日期格式是这样的 解决方案,添加 value-format="yyyy-MM-dd" <el-date-picker type= ...
- session 在PC端正常设置读取,在移动端无法正常读取
一.背景 最近在做一个面向三端[H5.IOS.安卓]的短信验证码登录接口.发送短信验证码时,服务端通过 session 保存验证码的值.登录时,从 session 获取验证码和用户输入的验证码 相比较 ...
- ERROR: Cannot uninstall 'chardet'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
pip 安装 docker库报错: ERROR: Cannot uninstall 'chardet'. It is a distutils installed project and thus we ...
- Android架构组件——ViewModel
概述 ViewModel,从字面上理解的话,它肯定是跟视图(View)以及数据(Model)相关的.正像它字面意思一样,它是负责准备和管理和UI组件(Fragment/Activity)相关的数据类, ...
- JDK的安装(mac)
1.第一步安装brew 教学网址 2.用brew安装jdk. brew update brew cask install java(未翻墙时长很长,大概猴年马月两个小时) 安装完成后就可以执行JAVA ...
- c# Directory类的常用方法
- Python日记(二):Python之禅
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Si ...
- System V共享内存
目录 1. 概述 2. System V共享内存API shmget shmat shmdt shmctl 3. 简单的程序 代码实现 common.h shmcreate.c shmrmid.c s ...
- jmeter性能测试监控
Jmeter监控服务器资源配置如下: 1.进入https://jmeter-plugins.org/downloads/all/下载plugins-manager.jar,放置到jmeter安装目录/ ...