My集合框架第五弹 最小堆

二叉堆(以最小堆为例),其具有结构性质和堆序性质
结构性质: 堆是一棵完全的二叉树,一颗高为h的完全二叉树有2^h到2^h-1个节点,高度为log N
            而且该结构可以很容易的使用数组来表示:对于数组中任一位置i上的元素,其左儿子在位置2i上,右儿子在2i+1,其父节点在[x/2]处
堆序性质:在一个堆中,对于每一个节点X,X的父亲中的关键字小于或等于X中的关键字
          也就是说:最小元总可以在根处找到

主要的操作为插入和删除:

以数组存储为例,算法在代码中体现:

     /**
	 * 向堆中插入元素x,
	 * 利用堆的性质,在一个堆中,对于每一个节点X,X的父亲中的关键字都小于或者等于X中的关键字,
	 * ps根节点除外(根节点没有父节点),时间复杂度为logN
	 * step1:如果堆没有满,在完全二叉树的下一个位置插入一个空穴
	 * step2:判断空穴是否存在父节点,如果不存在,直接插入;否则,step3;
	 * step3:(x.value>=[x/2].value)?step4:step5;
	 * step4:将X直接放在该空穴,return
	 * step5:将父节点的值移入空穴中,空穴就朝着根的方向上前进,回到step2;
	 * @param x
	 */
	public void insert(Comparable x){
		if(cursize == array.length-1){
			//堆已经满了,需要重新调整
			rebuild();
		}
		if(cursize==0){
			//没有父节点
			array[1] = x;
			cursize++;
		}else{
			int temp = ++cursize;
			while(temp>1 && x.compareTo(array[temp/2])<0){
				//父节点下移
				array[temp] =array[temp/2];
				temp/=2;
			}
			//空穴插入
			array[temp] = x;
		}
	}

删除操作:

        /**
	 * 删除堆中的最小元素并返回,方式与插入向反,时间复杂度为logN
	 * step1:将根节点出视为空穴X
	 * step2:if(空穴X的左右子树都存在) step3;else if(空穴只存在左子树) step4 ;else step5
	 * step3:if(空穴的X的左子树2X>X的右子树2X+1) 空穴<-->右子树;else 空穴<-->左子树;finally 继续step2
	 * step4:空穴和左子树交换,空穴已就位,且满足完全二叉树的要求
	 * step5:空穴和最后一个元素交换位置
	 * @return
	 */
	public Comparable deleteMin(){
		if(isEmpty())
			return null;
		Comparable min = array[1];
		int temp = 1;
		while(2*temp<=cursize){
			if(2*temp+1<=cursize){
				//左右子树都存在
				if(array[2*temp].compareTo(array[2*temp+1])>0){
					array[temp] = array[2*temp+1];
					temp = 2*temp+1;
				}else{
					array[temp] = array[2*temp];
					temp = 2*temp;
				}
			}else{
				//只存在左子树
				array[temp] = array[2*temp];
				temp = 2*temp;
			}
		}
		array[temp] = array[cursize--];
		return min;
	}

测试代码:

        @Test
	public void test() {
		BinaryHeap heap = new BinaryHeap();
		for(int i = 19;i>1;i--){
			heap.insert(i);
//			heap.printHeap();
		}
		while(!heap.isEmpty()){
			System.out.print(heap.deleteMin()+"\t");
		}
	}

结果:

好饿啊。。。。。。。。。。。。。。

时间: 2024-10-07 04:00:08

My集合框架第五弹 最小堆的相关文章

My集合框架第六弹 左式堆

左式堆(Leftist Heaps)又称作最左堆.左倾堆.左式堆作为堆的一种,保留了堆的一些属性. 第1,左式堆仍然以二叉树的形式构建: 第2,左式堆的任意结点的值比其子树任意结点值均小(最小堆的特性).但和一般的二叉堆不同,左式堆不再是一棵完全二叉树(Complete tree),而且是一棵极不平衡的树. package com.wpr.collection; /** * 左式堆:二叉堆缺点,首先,只能查找最小元素:其次,将两个堆合并的操作很麻烦 * 注意:所有支持有效合并的高级数据结构都需要

Java 集合框架(五):阻塞队列

阻塞队列 如果我们想要在线程安全的场景下使用队列,只有两个选择,一个是上面讲过的 ConcurrentLinkedQueue,还有就是我们要将的阻塞队列. 从名字我们就可以判断出阻塞队列适用的场景,那就是生产者消费者模式.阻塞对垒的添加和删除操作在队列满或者空的时候会被阻塞.这就保证了线程安全. 阻塞队列提供了四种处理方法: 方法 抛异常 返回特殊值 一直阻塞 超时退出 插入 add(E e) offer(e) put(e) offer(e,time,unit) 删除 remove() poll

JAVA学习第三十七课(常用对象API)- 集合框架(五)— Set集合:TreeSet集合

一.LinkedHashSet集合 HashSet下有子类LinkedHashSet API文档关于LinkedHashSet的解释: 具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现.此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表.此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代.注意,插入顺序不 受在 set 中重新插入的 元素的影响.(如果在 s.contains(e) 返回 true 后立即调用 s.add(

Java集合框架(五)—— Map、HashMap、Hashtable、Properties、SortedMap、TreeMap、WeakHashMap、IdentityHashMap、EnumMap

Map Map用于保存具有映射关系的数据,因此Map集合里保存着两组值,一组值用于保存Map里的key,另一组值用于保存Map里的value,key和value都可以是任何引用类型的数据.Map的key不容许重复,即同一个Map对象的任何两个key通过equals方法比较总是返回false. key和value之间存在单向一对一关系,即通过指定的key,总能找到唯一的.确定的value.从Map中取出数据时,只要给出指定的key,就可以取出对应的value. 如果把Map里的所有key放在一起看

My集合框架第三弹 AVL树

旋转操作: 由于任意一个结点最多只有两个儿子,所以当高度不平衡时,只可能是以下四种情况造成的: 1. 对该结点的左儿子的左子树进行了一次插入. 2. 对该结点的左儿子的右子树进行了一次插入. 3. 对该结点的右儿子的左子树进行了一次插入. 4. 对该结点的右儿子的右子树进行了一次插入. 向AVL树插入节点后,需要让AVL树重新平衡 step1:从插入节点向根节点溯源,观察是否存在不平衡节点(左右子树高度差),    if(不存在),return    else  step2step2:标记不平衡

My集合框架第四弹 HashTable(链表解决冲突)

package com.wpr.collection; import java.util.LinkedList; import java.util.List; public class HashTable<AnyType> { private static final int DEFAULT_TABLE_SIZE = 101; private List<AnyType>[] theList; private int curSize; public HashTable() { thi

JAVA学习第三十五课(常用对象API)- 集合框架(三)—Vector、LinkedList、ArrayList集合演示

集合框架构成图 摘自百度图片 一.Vector集合 演示 虽然Vector已经不常用了,但是还是要了解一下其中的方法 import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.Vector

Java零基础学习(五)集合框架

以前集合框架是面试的主要内容,但是现在因为考的太多,反而不会问太多,只要天南海北的说,说到面试官觉得你完全准备了解过,便不会再多问.这里有张自己画的图可以理解下. 原文地址:https://www.cnblogs.com/lovejoying/p/9609396.html

JAVA集合框架

收藏 查看我的收藏 146有用+1 56 编辑 Java,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台的总称.用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台.动态的Web.Internet计算.从此,Java被广泛接受并推动了Web的迅速发展,常用的浏览器现在均支持Java applet.集合框架是为表示和操作集合而规定的一种统一的标准的体系结构.任何集合框架都包含三大块内容:对外的接口.接口的实