优先队列priority queue是同意至少下列两种操作的数据结构:insert插入以及deleteMin(删除最小者),它的工作是找出,返回并删除优先队列中最小的元素。insert操作等价于enqueue入队。而deleteMin则是dequeue出队在优先队列中的等价操作。

一种实现优先队列的方法是使用二叉堆binary heap,它的使用对于优先队列的实现相当普遍,以至于当堆heap这个词不加修饰地用在优先队列的上下文中时,一般都是指数据结构的这样的实现。在本节。我们把二叉堆仅仅叫做堆。像二叉查找树一样,堆也有两个性质,即结构性和堆序性。恰似AVL树,对堆的一次操作可能破坏这两个性质中的一个。因此,堆得操作必须到堆得全部性质都被满足时才干终止。其实这并不难做到。

堆是一棵被全然填满的二叉树,有可能的例外是在底层。底层上的元素从左到右填入。这种树称为全然二叉树。easy证明。一棵高为h的全然二叉树有2^h到2^(h+1)-1个节点。

这意味着全然二叉树的高是logN向下取整,显然它是O(logN)。

一个重要的观察发现,由于全然二叉树这么有规律,所以它能够用一个数组表示而不须要使用链。对于数组中任一位置i上的元素。其左儿子在位置2i上,右儿子在左儿子后的单元(2i+1)中,它的父亲则在位置i/2中。因此,这里不仅不须要链。并且遍历该树所须要的操作极简单。在大部分计算机上执行非常可能非常快。这样的实现的唯一问题在于,最大的堆大小须要事先预计。但一般这并不成问题。

下面是一个二叉堆的实现:

  1. import java.util.NoSuchElementException;
  2. import java.util.Random;
  3.  
  4. public class BinaryHeap<AnyType extends Comparable<? super AnyType>> {
  5. private static final int DEFAULT_CAPACITY = 10;// 默认容量
  6. private int currentSize; // 当前堆大小
  7. private AnyType[] array; // 数组
  8.  
  9. public BinaryHeap() {
  10. this(DEFAULT_CAPACITY);
  11. }
  12.  
  13. @SuppressWarnings("unchecked")
  14. public BinaryHeap(int capacity) {
  15. currentSize = 0;
  16. array = (AnyType[]) new Comparable[capacity + 1];
  17. }
  18.  
  19. @SuppressWarnings("unchecked")
  20. public BinaryHeap(AnyType[] items) {
  21. currentSize = items.length;
  22. array = (AnyType[]) new Comparable[(currentSize + 2) * 11 / 10];
  23. int i = 1;
  24. for (AnyType item : items) {
  25. array[i++] = item;
  26. }
  27. buildHeap();
  28. }
  29.  
  30. /**
  31. * 从随意排列的项目中建立堆,线性时间执行
  32. */
  33. private void buildHeap() {
  34. for (int i = currentSize / 2; i > 0; i--) {
  35. percolateDown(i);
  36. }
  37. }
  38.  
  39. /**
  40. * 堆内元素向下移动
  41. *
  42. * @param hole
  43. * 下移的開始下标
  44. */
  45. private void percolateDown(int hole) {
  46. int child;
  47. AnyType tmp = array[hole];
  48. for (; hole * 2 <= currentSize; hole = child) {
  49. child = hole * 2;
  50. if (child != currentSize
  51. && array[child + 1].compareTo(array[child]) < 0) {
  52. child++;
  53. }
  54. if (array[child].compareTo(tmp) < 0) {
  55. array[hole] = array[child];
  56. } else {
  57. break;
  58. }
  59. }
  60. array[hole] = tmp;
  61. }
  62.  
  63. /**
  64. * 插入一个元素
  65. *
  66. * @param x
  67. * 插入元素
  68. */
  69. public void insert(AnyType x) {
  70. if (isFull()) {
  71. enlargeArray(array.length * 2 + 1);
  72. }
  73. int hole = ++currentSize;
  74. for (; hole > 1 && x.compareTo(array[hole / 2]) < 0; hole /= 2) {
  75. array[hole] = array[hole / 2];
  76. }
  77. array[hole] = x;
  78. }
  79.  
  80. /**
  81. * 堆是否满
  82. *
  83. * @return 是否堆满
  84. */
  85. public boolean isFull() {
  86. return currentSize == array.length - 1;
  87. }
  88.  
  89. /**
  90. * 堆是否空
  91. *
  92. * @return 是否堆空
  93. */
  94. public boolean isEmpty() {
  95. return currentSize == 0;
  96. }
  97.  
  98. /**
  99. * 清空堆
  100. */
  101. @SuppressWarnings("unused")
  102. public void makeEmpay() {
  103. currentSize = 0;
  104. for (AnyType anyType : array) {
  105. anyType=null;
  106. }
  107. }
  108.  
  109. /**
  110. * 找到堆中最小元素
  111. * @return 最小元素
  112. */
  113. public AnyType findMin() {
  114. if (isEmpty())
  115. return null;
  116. return array[1];
  117. }
  118.  
  119. /**
  120. * 删除堆中最小元素
  121. * @return 删除元素
  122. */
  123. public AnyType deleteMin() {
  124. if (isEmpty()) {
  125. throw new NoSuchElementException();
  126. }
  127. AnyType minItem = findMin();
  128. array[1] = array[currentSize];
  129. array[currentSize--] = null;
  130. percolateDown(1);
  131. return minItem;
  132. }
  133.  
  134. /**
  135. * 扩大数组容量
  136. * @param newSize 新的容量
  137. */
  138. @SuppressWarnings("unchecked")
  139. private void enlargeArray(int newSize) {
  140. AnyType[] old = array;
  141. array = (AnyType[]) new Comparable[newSize];
  142. for (int i = 0; i < old.length; i++) {
  143. array[i] = old[i];
  144. }
  145. }
  146.  
  147. /**
  148. * 输出数组中的元素
  149. */
  150. public void printHeap() {
  151. for (AnyType anyType : array) {
  152. System.out.print(anyType + " ");
  153. }
  154. }
  155.  
  156. public static void main(String[] args) {
  157. BinaryHeap<Integer> heap = new BinaryHeap<Integer>();
  158. for (int i = 0; i < 20; i++) {
  159. heap.insert(i);
  160. }
  161. heap.deleteMin();
  162. heap.deleteMin();
  163. heap.deleteMin();
  164. heap.printHeap();
  165. }
  166. }

运行结果:

null 3 4 5 7 9 11 6 15 8 17 10 18 12 13 14 19 16 null null null null null

数据结构(Java语言)——BinaryHeap简单实现的更多相关文章

  1. Java语言实现简单FTP软件------>FTP软件主界面的实现(四)

    首先看一下该软件的整体代码框架                        1.首先介绍程序的主入口FTPMain.java,采用了一个漂亮的外观风格 package com.oyp.ftp; im ...

  2. Java语言实现简单FTP软件------>源码放送(十三)

    Java语言实现简单FTP软件------>FTP协议分析(一) Java语言实现简单FTP软件------>FTP软件效果图预览之下载功能(二) Java语言实现简单FTP软件----- ...

  3. Java语言实现简单FTP软件------>上传下载管理模块的实现(十一)

    1.上传本地文件或文件夹到远程FTP服务器端的功能. 当用户在本地文件列表中选择想要上传的文件后,点击上传按钮,将本机上指定的文件上传到FTP服务器当前展现的目录,下图为上传子模块流程图 选择好要上传 ...

  4. 数据结构--Java语言描述

    本篇文章是为了记录自己在学习数据结构时的笔记,会对常见的数据结构做基本的介绍以及使用Java语言进行实现.包括 动态数组 栈 队列 链表 二分搜索树 优先队列和堆 线段树 Trie树 并查集 AVL树 ...

  5. 数据结构(Java语言描述)-第一章:概述

    第一章 概述 1.0 序言 自己为啥要学数据结构嘞,我觉得主要有以下三个原因: 前段时间在看并发编程时,发现aqs,corrunthashmap等底层都用到了数据结构,主要的有队列,还有链表,学习数据 ...

  6. 用Java语言实现简单的词法分析器

    编译原理中的词法分析算是很重要的一个部分,原理比较简单,不过网上大部分都是用C语言或者C++来编写,笔者近期在学习Java,故用Java语言实现了简单的词法分析器. 要分析的代码段如下: 输出结果如下 ...

  7. Java语言的简单基础

    1.Java 是一种高级程序设计语言. 2.Java 是大小敏感的程序语言. 3.Java 中的 public 修饰的类名一般要与文件名相同,但也有特列:内部类. 4.Java 程序能在任何操作系统中 ...

  8. 设计模式(Java语言)- 简单工厂模式

    简单工厂模式有称为静态工厂模式,属于设计模式中的创建型模式.简单工厂模式通过对外提供一个静态方法来统一为类创建实例.简单工厂模式的目的是实现类与类之间解耦,其次是客户端不需要知道这个对象是如何被穿创建 ...

  9. java语言实现简单接口工具--粗简版

    2016注定是变化的一年,忙碌.网红.项目融资失败,现在有点时间整整帖子~~ 目标: 提高工作效率与质量,能支持平台全量接口回归测试与迭代测试也要满足单一接口联调测试. 使用人员: 测试,开发 工具包 ...

  10. Java语言实现简单FTP软件------>FTP软件本地窗口的实现(五)

    1.首先看一下本地窗口的布局效果 2.看一下本地窗口实现的代码框架 2.本地窗口的具体实现代码LocalPanel.java package com.oyp.ftp.panel.local; impo ...

随机推荐

  1. (十一)__LINE__、__FUNCTION__的使用

    单片机中也可以用__LINE和__FUNCTION__进行异常信息打印,分别代表当前代码行数和当前代码函数名 printf("line:%d\r\n",__LINE__); pri ...

  2. 下载Instagram的图片

    1.接口地址 https://www.instagram.com/p/shortcode/?__a=1 如何获取shortcode 比如说文章地址是https://www.instagram.com/ ...

  3. python访问网站

    #!/usr/bin/env python # encoding: utf-8 from functools import wraps import requests from lxml import ...

  4. Android的简单应用(四)——字符串处理

    在Java中,对字符串进行处理的方法很多,也可以通过导入相应的字符串处理的lib包来进行处理.不过今天要说的是Android中看到的两种处理字符串的方法. 一.正则表达式 其实正则表达式没有大家想象的 ...

  5. Django基础之路由系统

    Django的路由系统 Django 1.11版本 URLConf官方文档 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表. ...

  6. python os用法精简版

    import os print(os.getcwd()) #返回当前路径,无参数 print(os.listdir('E:\zsfile')) #该路径下所有文件名 os.remove('E:\zsf ...

  7. P1059 明明的随机数【去重排序】

    题目描述 明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应 ...

  8. [Python Debug]Kernel Crash While Running Neural Network with Keras|Jupyter Notebook运行Keras服务器宕机原因及解决方法

    最近做Machine Learning作业,要在Jupyter Notebook上用Keras搭建Neural Network.结果连最简单的一层神经网络都运行不了,更奇怪的是我先用iris数据集跑了 ...

  9. POJ 3537 Crosses and Crosses (NEERC)

                      Crosses and Crosses Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 4 ...

  10. [Contest20180415]看无可看

    题意:有一个数列$f$,对$\forall i\geq2,f_i=2f_{i-1}+3f_{i-2}$,给定$f_0,f_1$,再给定一个集合$S=\{a_{1\cdots n}\}$和$k$,求$\ ...