《Algorithms算法》笔记:优先队列(2)——二叉堆
二叉堆
1 二叉堆的定义
堆是一个完全二叉树结构(除了最底下一层,其他层全是完全平衡的),如果每个结点都大于它的两个孩子,那么这个堆是有序的。
二叉堆是一组能够用堆有序的完全二叉树排序的元素,并在数组中按照层级存储(不用数组的第一个位置)
2 二叉堆的性质
- 最大的元素在a[1] (root结点)
- 每个k的父亲在k/2
- 每个k的孩子在k*2和k*2+1
3 二叉堆的操作
3.1 上浮(孩子大于父亲)——对应插入操作
循环,每次比较自己和父亲,如果比父亲大就交换,直到root。
/1459052884043.png)
3.2 插入
先把元素加入数组的最后一个位置,然后进行上浮到正确位置
/1459053166677.png)
3.3 下沉(父亲小于儿子)——对应删除操作
循环,每次比较自己和两个孩子,如果比孩子小就交换,如果比两个孩子都小,就交换到两个里面较大的一个。直到叶子。
/1459053088200.png)
3.4 删除最大元素
先把根元素与最后一个元素交换,删除最后一个元素,然后从根开始下沉到正确位置。
4 二叉堆优先队列代码
/**
 *
 * @author rocky
 */
public class MaxPQ<Key extends Comparable<Key>> {
    private Key[] pq;
    private int N;
    public MaxPQ(int capacity) {
        pq = (Key[]) new Comparable[capacity + 1];
    }
    public boolean isEmpty() {
        return N == 0;
    }
    public void insert(Key key)
    {
        N++;
        pq[N] = key;
        swim(N);
    }
    public Key delMax() {
        Key max = pq[1];  //get the max element
        exch(1, N);     //exchange between the root and the last element
        N--;
        sink(1);   //sink to the right place
        pq[N+1] = null;   //delete
        return max;
    }
    private void swim(int k)
    {
        while(k > 1 && less(k/2, k))
        {
            exch(k, k/2);
            k /= 2;
        }
    }
    private void sink(int k) {
        while(k*2 <= N)    //if this node has left child
        {
            int child = k * 2;
            if (child < N && less(child, child + 1)) {  //if the left child is less than the right child
                child = child + 1;   //change child to the right child
            }
            if (less(k, child)) {
                exch(k, child);
            }
            k = child;
        }
    }
    private boolean less(int i, int j) {
        return pq[i].compareTo(pq[j]) < 0;
    }
    private void exch(int i, int j) {
        Key t = pq[i];
        pq[i] = pq[j];
        pq[j] = t;
    }
}
5 二叉堆扩展
/1459054902637.png)
5.1 不可变性
我们算法的前提是用户不会改变队列的元素,如果用户能改变队列的元素,那么队列成立的条件就会破坏, 
不可变的数据类型,就是说一个实例一旦建立,就不可以改变。java里很多类型都是不可变的。
/1459055625775.png)
这有很多好处,但是坏处就是如果你需要改变值必须要新建一个对象。
/1459055650769.png)
《Algorithms算法》笔记:优先队列(2)——二叉堆的更多相关文章
- 图论——Dijkstra+prim算法涉及到的优先队列(二叉堆)
		[0]README 0.1)为什么有这篇文章?因为 Dijkstra算法的优先队列实现 涉及到了一种新的数据结构,即优先队列(二叉堆)的操作需要更改以适应这种新的数据结构,我们暂且吧它定义为Dista ... 
- 【算法与数据结构】二叉堆和优先队列 Priority Queue
		优先队列的特点 普通队列遵守先进先出(FIFO)的规则,而优先队列虽然也叫队列,规则有所不同: 最大优先队列:优先级最高的元素先出队 最小优先队列:优先级最低的元素先出队 优先队列可以用下面几种数据结 ... 
- 优先队列之二叉堆与d-堆
		二叉堆简介 平时所说的堆,若没加任何修饰,一般就是指二叉堆.同二叉树一样,堆也有两个性质,即结构性和堆序性.正如AVL树一样,对堆的以此操作可能破坏者两个性质中的一个,因此,堆的操作必须要到堆的所有性 ... 
- 优先队列的二叉堆Java实现
		package practice; import edu.princeton.cs.algs4.StdRandom; public class TestMain { public static voi ... 
- PriorityBlockingQueue优先队列的二叉堆实现
		转载请注明原创地址http://www.cnblogs.com/dongxiao-yang/p/6293807.html java.util.concurrent.PriorityBlockingQu ... 
- 数据结构与算法——优先队列类的C++实现(二叉堆)
		优先队列简单介绍: 操作系统表明上看着是支持多个应用程序同一时候执行.其实是每一个时刻仅仅能有一个进程执行,操作系统会调度不同的进程去执行. 每一个进程都仅仅能执行一个固定的时间,当超过了该时间.操作 ... 
- 纯数据结构Java实现(6/11)(二叉堆&优先队列)
		堆其实也是树结构(或者说基于树结构),一般可以用堆实现优先队列. 二叉堆 堆可以用于实现其他高层数据结构,比如优先队列 而要实现一个堆,可以借助二叉树,其实现称为: 二叉堆 (使用二叉树表示的堆). ... 
- Python实现二叉堆
		Python实现二叉堆 二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树).二叉堆有两种:最大堆和最小堆.最大堆:父结点的键值总是大于或等于任何一个子节点的键值:最小堆: ... 
- 二叉堆的BuildHeap操作
		优先队列(二叉堆)BuildHeap操作 \(BuildHeap(H)\)操作把\(N\)个关键字作为输入并把它们放入空堆中.显然,这可以使用\(N\)个相继的\(Insert\)操作来完成.由于每个 ... 
随机推荐
- javax/faces/webapp/FacesServlet
			严重: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component ... 
- linux 下用户管理
			linux 下用户管理 一.用户的分类 1.超级用户:root UID=0 2.系统用户:不需要登录系统,对应用程序服务,主要维护系统的正常运行:UID = 1 ~ 499(RHEL7 = 1 ~ 9 ... 
- POJ2392Space Elevator(贪心+背包)
			Space Elevator Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9970 Accepted: 4738 De ... 
- ci创建zip
			public function createZip() { $this->load->library("zip"); $name = "test.text&q ... 
- javaweb学习总结(三十一)——国际化(i18n)
			一.国际化开发概述 软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的.符合来访者阅读习惯的页面或数据. 国际化(internationaliz ... 
- 字符串匹配的Boyer-Moore算法 详解 加 C# 实现
			上一篇文章,我介绍了KMP算法. 但是,它并不是效率最高的算法,实际采用并不多.各种文本编辑器的"查找"功能(Ctrl+F),大多采用Boyer-Moore算法. Boyer-Mo ... 
- 一个令人蛋疼的 Microsoft.AspNet.FriendlyUrls
			我一个项目都基本上做完了,结果部署到我服务器的时候结果一直报404 找不到 一看global.asax有个路由注册的代码 public static void RegisterRoutes(Route ... 
- Jni中C++和Java的参数传递  参数对照
			Jni中C++和Java的参数传递 如何使用JNI的一些基本方法和过程在网上多如牛毛,如果你对Jni不甚了解,不知道Jni是做什么的,如何建立一个基本的jni程序,或许可以参考下面下面这些文章:利用V ... 
- JAVA 利用JNI加密class文件/自定义ClassLoader 类
			利用 JNI 对bytecode 加密.不影响java程序员的正常开发.09年的时候写的,现在拿出来晒晒————————————————————————————混淆才是王道,如果混淆再加密就更酷了.. ... 
- 通用js类库
			/* 其它通用函数 */$(function() { // var General = function() { var _self = this; /* 写 cookie 操作 */ _self.S ... 
 
			
		/1459052642114.png)