栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

堆(minHeap/maxHeap)的原理及其实现(java)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

堆(minHeap/maxHeap)的原理及其实现(java)

  堆(heap,特殊的完全二叉树),为了实现优先队列(对队列中对最大或者最小M个元素进行跟踪)而产生。


满足条件
  使用minHeap作为例子,maxHeap类似。
  min:每个节点的值都小于/等于它的child;
  complete biTree:满足完全二叉树的特性。


Operation
insert
  1.将新的node插入叶子节点坐在层的最末端(维护complete biTree);
  2.将该node和其parent node进行比较,如果不满足min的特性,交换两个节点的值;
  3.重复2过程直至满足条件。

remove
  1.将root的值用最末端的叶子节点代替,删除该叶子节点(维护complete biTree);
  2.将root的值和其left和right child进行比较。如果不满足min的特性,将root和child中较小的值进行交换;
  3.重复2过程直至满足条件。


maxHeap
(很有趣的一个问题)对于数值型的maxHeap,如何使用现有的minHeap实现?
  在构建minHeap时,将所有的值取反。


底层实现
  利用heap完全二叉树的特性,使用数组按照BFS的顺序存放其值即可(一般在数组头部空置一个value,或者存节点的个数,方便计算)。

java代码

public class Heap {
    
    private T[] heap;
    private int originSize; // 定义初始容量为10
    private int last;

    Heap() {
        originSize = 10;
        last = 1;
        this.heap = (T[]) new Comparable[originSize];
    }

    public void insert(T a) {
        this.heap[last] = a;
        int curNode = last;
        while (curNode / 2 > 0 && !checkUpMin(curNode)) {
            exchange(curNode, curNode / 2);
            curNode /= 2;
        }
        last += 1;
    }

    private boolean checkUpMin(int a) {
        
        int b = a / 2;
        return getCur(a).compareTo(this.heap[b]) >= 0;
    }

    private T getCur(int a) {
        
        return this.heap[a];
    }

    private T getLeft(int a) {
        
        int idx = a * 2;
        if (idx < last) {
            return getCur(idx);
        }
        return null;
    }

    private T getRight(int a) {
        
        int idx = a * 2 + 1;
        if (idx < last) {
            return getCur(idx);
        }
        return null;
    }

    private void exchange(int a, int b) {
        
        T temp = getCur(a);
        this.heap[a] = getCur(b);
        this.heap[b] = temp;
    }

    public T removeMin() {
        T res = null;
        if (last <= 1) {
            return res;
        } else {
            res = this.heap[1];
            last -= 1;
            this.heap[1] = getCur(last);
            int curNode = 1;
            while (curNode < last && !checkDownMin(curNode)) {
                int minChild = getMinChild(curNode);
                exchange(curNode, minChild);
                curNode = minChild;
            }
        }
        return res;
    }

    private boolean checkDownMin(int a) {
        
        int idx = getMinChild(a);
        if (idx == a) {
            return true;
        }
        return getCur(a).compareTo(getCur(idx)) <= 0;
    }

    private int getMinChild(int a) {
        
        int res;
        if (isLeaf(a)) {
            res = a;
        } else if (onlyLeftExit(a)) {
            res = a * 2;
        } else if (onlyRightExit(a)) {
            res = a * 2 + 1;
        } else {
            res = a * 2;
            if (getLeft(a).compareTo(getRight(a)) > 0) {
                res += 1;
            }
        }
        return res;
    }

    private boolean isLeaf(int a) {
        
        return getLeft(a) == null && getRight(a) == null;
    }

    private boolean onlyLeftExit(int a) {
        
        return getLeft(a) != null && getRight(a) == null;
    }

    private boolean onlyRightExit(int a) {
        
        return getLeft(a) == null && getRight(a) != null;
    }

    public static void main(String[] args) {
        
        Heap test = new Heap<>();
        test.insert(9);
        test.insert(5);
        test.insert(1);
        test.insert(4);
        test.insert(7);
        test.insert(3);
        for (int i = 0; i < 6; i++) {
            System.out.print(test.removeMin() + " "); // 应该按照1 3 4 5 7 9的顺序输出
        }
    }
}



To be a sailor of the world bound for all ports.
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/825404.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号