数据结构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.节点颜色要 ...
随机推荐
- docker-compose的一些服务一直是restarting
1.查看日志 docker logs jenkins(镜像名字) 1.1 可能权限问题 1.2可能内存问题
- 如何在textarea多行文本框中设置滚动条样式
其中设置滚动条的组成都有以下部分 ::-webkit-scrollbar 滚动条整体部分 ::-webkit-scrollbar-thumb 滚动条里面的小方块,能向上向下移动(或往左往右移动,取决 ...
- Linux下使用nextcloud搭建个人网盘
市面上有那么多的网盘服务提供商,为什么还要自己搭建网盘呢?主要有以下原因: 免费的网盘都有种种限制,要么不限速容量小(onedriver,google driver),要么容量大限速(百度云) 付费网 ...
- css小技巧 --> 单标签实现单行文字居中,多行文字居左
可能出现的尺寸场景: 代码如下: <!DOCTYPE html> <html lang="zh"> <head> <meta charse ...
- HTML5新增元素和移除的元素?
新增元素: 图像Canvas 多媒体video.audio 本地存储localStorage.sessionStorage 语义化更好的内容元素aticle.header.footer.nav.sec ...
- git 出现 fatal: remote origin already exists 错误
当输入$ git remote add origin git@github.com:djqiang(github帐号名)/gitdemo(项目名).git 出现 如下错误: 解决办法如下: 1.先输入 ...
- unity 3D物体使用EventSystem响应事件
在ugui中创建一个canvas 之后会自动创建一个EventSystem,用来处理UI上的时间响应.(可以通过UI>EventSystem创建EventSystem) EventSystem ...
- SpringBoot 中的使用事务
转自:https://blog.csdn.net/linzhiqiang0316/article/details/52638039 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数 ...
- maven报错找不到依赖
遇到一个巨坑 跑公司的一个项目,拉下来代码,跑不起来.发现maven一直报这个错 was cached in the local repository,resolution will not be r ...
- djangCrm
---恢复内容开始--- 一> 在数据库进行循环取多对多 def get_classlist(self): l=[] for cls in self.class_list.all(): l.ap ...