美文网首页
堆 - Heap

堆 - Heap

作者: 反射弧长一光年 | 来源:发表于2019-01-06 05:50 被阅读0次

基本概念

堆是一种数据结构,定义为一棵完全二叉树。假如用数组储存堆结构,那么对于某个index为i的节点来说,它的左儿子的index为2*i+1,右儿子为2*i+2
堆有两种,小根堆和大根堆。对于小根堆,它的每个节点的值都小于该节点左右儿子的值。同理大根堆。

堆的操作

  • 堆化(heapify)
    O(n)
    表面上看heapify应该为O(nlogn),但是对于在第h-i层的节点来说,它最多的shiftdown深度为ishiftdown每一层的复杂度为O(1),而第h - i层一共有2 ^ {h - i}个节点, 所以整个heapify的时间复杂度为:
    2^{h - 1} *1 + 2^{h - 2} *2 +...+ 2^{1} *(h - 1) + h
    这是一个等比数列,通过将它乘以2,并做差,得到:
    2^{h+1} - 2 - h
    因为h = logn,所以heapify的时间复杂度为O(n)
public class Heap {
    
    public void heapify(int[] A) {
        for (int i = (A.length - 2) / 2; i >= 0; i--) {
            shiftdown(A, i);
        }
    }
    
    public void shiftdown(int[] A, int k) {
        int n = A.length;
        int minIndex = k;
        int left = 2 * k + 1;
        int right = 2 * k + 2;
        if (left < n && A[left] < A[minIndex]) {
            minIndex = left;
        }
        if (right < n && A[right] < A[minIndex]) {
            minIndex = right;
        }
        if (minIndex != k) {
            int tmp = A[k];
            A[k] = A[minIndex];
            A[minIndex] = tmp;
            shiftdown(A, minIndex);
        }
    }
}
  • 添加
    O(logn)
  • 删除
    O(logn)
  • 返回堆顶
    O(1)
public class minHeap {
    
    int[] A;
    int size;
    int maxSize;
    
    public minHeap(int n) {
        A = new int[n];
        size = 0;
        maxSize = n;
    }
    
    public void add(int x) {
        if (size == A.length) {
            return;
        }
        A[size] = x;
        shiftup(size);
        size++;
    }
    
    public int poll() {
        if (size == 0) {
            return Integer.MIN_VALUE;
        }
        size--;
        swap(0, size);
        shiftdown(0);
        return A[size];
    }
    
    public int peek() {
        if (size == 0) {
            return Integer.MIN_VALUE;
        }
        return A[0];
    }
    
    private void shiftdown(int k) {
        int minIndex = k;
        int left = 2 * k + 1;
        int right = 2 * k + 2;
        if (left < size && A[left] < A[minIndex]) {
            minIndex = left;
        }
        if (right < size && A[right] < A[minIndex]) {
            minIndex = right;
        }
        if (minIndex != k) {
            swap(minIndex, k);
            shiftdown(A, minIndex);
        }
    }
    
    private void shiftup(int k) {
        int parent = k / 2;
        if (A[k] < A[parent]) {
            swap[k, parent];
            shiftup(parent);
        }
    }
    
    private void swap(int a, int b) {
        int tmp = A[a];
        A[a] = A[b];
        A[b] = tmp;
    }
}
  • Java 内置PriorityQueue
PriorityQueue<Integer> heap = new PriorityQueue<>(size, new Comparator<Integer>() {
        @Override
        public int compare {
                return a - b; // 小根堆 
                return b - a; // 大根堆
        }
});
heap.offer(); // 添加
heap.poll(); // 删除
heap.peek(); // 返回堆顶元素,即最小或最大值

Lintcode 相关练习

Top k Largest Numbers II
K Closest Points

相关文章

  • 堆Heap

    Heap Heap: 堆。一般也称作Priority Queue(即优先队列) 堆我们一般用一个二叉树来表示。即一...

  • heap (堆)

    堆: 说实话在仔细研究堆之前,我一直将它跟堆栈混为了一个东西。还想着这是一个后进先出的东西。我们来看一下什么是堆:...

  • Heap 堆

    两种Heap Structure: 1. Max Heap parent node比 children node大...

  • 堆:Heap

    一:堆的介绍 Heap是一种数据结构具有以下的特点:1)完全二叉树;2)heap中存储的值是偏序; Min-hea...

  • 堆 (Heap)

    “堆”这种数据结构常用在“优先级队列”的实现上, 比如Java中的PriorityQueue。今天讲讲什么是堆,如...

  • 堆(Heap)

    堆(Heap) 堆是一种常用的树形结构,是一种特殊的完全二叉树,当且仅当满足所有节点的值总是不大于或不小于其父节点...

  • 堆(heap)

    什么是堆? 堆是满足下面两个条件的一种二叉树 它是一棵完全二叉树; 堆中每个节点的值都必须大于等于(大根堆)或者小...

  • 堆 - Heap

    基本概念 堆是一种数据结构,定义为一棵完全二叉树。假如用数组储存堆结构,那么对于某个index为i的节点来说,它的...

  • 堆(heap)

    如何理解“堆”? 堆是一种特殊的树。满足两点要求。 堆是一个完全二叉树;完全二叉树要求,除了最后一次,其他层的节点...

  • 堆-Heap

    堆-Heap 堆的基本接口设计 二叉堆(最大堆) 大顶堆-添加 大顶堆-删除 删除堆顶元素的同时插入一个新元素 大...

网友评论

      本文标题:堆 - Heap

      本文链接:https://www.haomeiwen.com/subject/xmolrqtx.html