自古美人都是妖i 提交于 2019-11-26 21:13:54

概述

  堆是一种完全二叉树,分为两种类型:

    大顶堆:每一个非叶子结点均不小于其孩子结点。

    小顶堆:每一个非叶子结点均不大于其孩子结点。

  

  堆中根结点的位置称为堆顶,最后结点的位置称为堆尾,结点个数称为堆长度。由于结点从1开始编号,所以堆尾的结点编号等于其堆长度。

  堆有以下特性:

    a.对于大顶堆,堆顶元素是最大值。对于小顶堆,堆顶元素是最小值。

    b.对于大顶堆,堆顶的左右孩子结点中元素值较大的为第二大值。对于小顶堆,堆顶的左右孩子结点中元素值较小的为第二小值。

  堆的特性常被用于实现排序。

  堆常用的操作有:

    插入:在堆尾后插入新结点。

    修改:修改某个结点的元素值,然后调整堆结构。

    删除:将某个结点与堆尾交换,然后删除堆尾,最后调整堆结构。

  堆接口的定义如下:

 1 /**
 2  * 堆
 3  */
 4 public interface Heap<E extends Comparable<E>> {
 5 
 6     /**
 7      * 堆类型
 8      */
 9     enum Tag {
10         /**
11          * 大顶堆
12          */
13         GREAT, 
14 
15         /**
16          * 小顶堆
17          */
18         LESS;
19     }
20 
21     /**
22      * 添加结点
23      * @param e
24      */
25     void add(E e);
26 
27     /**
28      * 修改指定结点的元素值,并重新调整
29      * @param index
30      * @param e
31      * @throws HeapException
32      */
33     void set(int index, E e) throws HeapException;
34 
35     /**
36      * 删除指定结点的元素值
37      * @param index
38      * @throws HeapException
39      */
40     void remove(int index) throws HeapException;
41 
42     /**
43      * 判断是否为空堆
44      * @return
45      */
46     boolean isEmpty();
47 
48     /**
49      * 获取堆中元素个数
50      * @return
51      */
52     int getNum();
53 
54     /**
55      * 判断是否为大顶堆
56      * @return
57      */
58     boolean isGreatHeap();
59 
60     /**
61      * 判断是否为小顶堆
62      * @return
63      */
64     boolean isLessHeap();
65 
66 }
Heap

  其抽象类定义如下:

 1 public abstract class AbstractHeap<E extends Comparable<E>> implements Heap<E> {
 2 
 3     /**
 4      * 堆长度
 5      */
 6     protected int num;
 7 
 8     /**
 9      * 堆类型
10      */
11     protected Tag tag;
12 
13     /**
14      * 计算父结点编号
15      * @param index
16      * @return
17      */
18     protected int getParentIndex(int index) {
19         return index % 2 == 0 ? index / 2 : (index - 1) / 2;
20     }
21 
22     /**
23      * 计算左子结点编号
24      * @param index
25      * @return
26      */
27     protected int getLchildIndex(int index) {
28         return 2 * index;
29     }
30 
31     /**
32      * 计算右子结点编号
33      * @param index
34      * @return
35      */
36     protected int getRchildIndex(int index) {
37         return 2 * index + 1;
38     }
39 
40     /**
41      * 检查是否为空堆
42      * @throws HeapException
43      */
44     protected void checkEmpty() throws HeapException {
45         if (isEmpty()) throw new HeapException("堆中没有元素!");
46     }
47 
48     /**
49      * 检查编号是否超出范围
50      * @param index
51      * @throws HeapException
52      */
53     protected void checkOutOfBounds(int index) throws HeapException {
54         checkEmpty();
55         if (index < 1) throw new HeapException("编号" + index + "必须为正数!");
56         if (index > num) throw new HeapException("编号" + index + "超出范围!");
57     }
58 
59     @Override
60     public boolean isEmpty() {
61         return num == 0;
62     }
63 
64     @Override
65     public int getNum() {
66         return num;
67     }
68 
69     @Override
70     public boolean isGreatHeap() {
71         return tag == Tag.GREAT;
72     }
73 
74     @Override
75     public boolean isLessHeap() {
76         return tag == Tag.LESS;
77     }
78 
79 }
AbstractHeap

  堆的存储结构分为顺序存储和链式存储。

  顺序存储结构如下:

  链式存储结构如下:

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!