二叉堆

作者: HWilliamgo | 来源:发表于2018-06-02 18:17 被阅读8次

《数据结构与算法:java语言描述》源码

package DataStructureAndAlgor;

import java.nio.BufferUnderflowException;

/**
 * 由数组实现的堆,小根堆。
 * <p>
 * 堆的定义:
 * 1. 堆中某个节点的值总是不大于或不小于其父节点的值(将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆)
 * 2. 堆总是一棵完全二叉树
 * <p>
 * 当堆用数组实现:
 * 1. 位置0不放元素,从位置1开始放。
 * 2. 数组任一位置i上的元素,左子树在位置2i,右子树在位置(2i+1),父结点在[i/2]上。
 *
 * @param <T>
 */
/*
    回顾的时候要画出这个模型,图上的数字代表数组下标,0下标为null。
                1
             /      \
            2         3          
          /  \       / \
         4     5    6    7
        / \    / \
       8  9   10 11       
 */
public class BinaryHeap<T extends Comparable<T>> {
    private static final int DEFAULT_CAPACITY = 10;
    private int currentSize;
    private T[] array;

    public BinaryHeap() {
        this(DEFAULT_CAPACITY);
    }

    public BinaryHeap(int capacity) {
        currentSize = 0;
        array = (T[]) new Comparable[capacity + 1];
    }

    public BinaryHeap(T[] items) {
        currentSize = items.length;
        array = (T[]) new Comparable[(currentSize + 2) * 11 / 10];

        int i = 1;
        for (T item : items) {
            array[i++] = item;
        }
        buildHeap();
    }

    public void insert(T x) {
        //通过上滤(percolate up),将新元素在堆中上滤直到找出正确位置。时间复杂度:O(logN)
        if (currentSize == array.length - 1) {
            enlargeArray(array.length * 2 + 1);
        }
        int hole = ++currentSize;
        for (; hole > 1 && x.compareTo(array[hole / 2]) < 0; hole /= 2) {/*(hole/2)表示父结点的位置*/
            array[hole] = array[hole / 2];
        }
        array[hole] = x;
    }

    public T findMin() {
        if (isEmpty()) {
            throw new BufferUnderflowException();
        }
        return array[1];//array[0]是不放元素的,array[1]才是root
    }

    public T deleteMin() {
        if (isEmpty()) {
            throw new BufferUnderflowException();
        }
        T minItem = findMin();
        array[1] = array[currentSize--];//直接将最后一个元素覆盖第一个元素
        //TODO :是否需要array[currentSize+1]=null;?
        percolateDown(1);//覆盖之后,开始“下滤”
        return minItem;
    }

    private boolean isEmpty() {
        return currentSize == 0;
    }

    public void makeEmpty() {
        currentSize = 0;
    }

    private void percolateDown(int hole) {//   O(logN)
        int child;
        T tmp = array[hole];//要"下滤"的元素。

        for (; hole * 2 <= currentSize; hole = child) {//hole*2<=currentSize是保证左子树下标不越界;
            child = hole * 2;                      //hole=child是下滤的直接操作。
            if (child != currentSize && array[child + 1].compareTo(array[child]) < 0) {//TODO:可以测试一下第一个判断条件的必要性
                child++;//如果右子树<左子树,下标换到右子树去。
            }
            if (array[child].compareTo(tmp) < 0) {//如果孩子结点小于父结点
                array[hole] = array[child];//将孩子结点"上移",hole"下滤"。
            } else {
                break;
            }
        }
        array[hole] = tmp;

    }

    private void buildHeap() {
        for (int i = currentSize / 2; i > 0; i--) {//除以二是因为后面的都是完全二叉树叶子结点,不需要下滤。
            percolateDown(i);
        }
    }

    private void enlargeArray(int newSize) {
        T[] old = array;
        array = (T[]) new Comparable[newSize];
        for (int i = 0; i < old.length; i++) {
            array[i] = old[i];
        }
    }

}


相关文章

  • 用go实现二叉堆插入删除构建

    二叉堆的插入: 二叉堆的删除: 二叉堆的构建:

  • [数据结构与算法-iOS 实现]二叉堆原理实现及top k 问题

    二叉堆 demo 二叉堆其实就是一颗完全二叉树,所以又可以叫做完全二叉堆 二叉堆的底层可以用数组来实现 对于二叉堆...

  • 二叉堆

    二叉堆定义 二叉堆是一种特殊的堆, 二叉堆是完全二叉树或者近似完全二叉树. 二叉堆满足堆特性: 父节点的键值总是保...

  • 二叉堆(Binary Heap)

    二叉堆这个数据结构有点意思,自己做了个总结,内容结构如下: 二叉堆性质 二叉堆操作 应用 二叉堆性质: 堆(Hea...

  • 堆排序(下):最大堆

    二叉堆,简称堆 Heap 尖的完全二叉树。也有三叉堆以及普通堆,但大部分时候堆就是指二叉堆 二叉堆的定义 一棵完全...

  • 二叉堆的Python实现

    二叉堆(binary heap)是一种特殊的堆,二叉堆是完全二叉树或者是近似完全二叉树。二叉堆满足堆特性:父节点的...

  • Sort.堆排序(heapsort) & 优先队列

    二叉堆 这个二叉堆和先进后出的那个堆不是一个。而且这个二叉堆从下标1开始存储元素。 这里的二叉堆是个数组,也可以看...

  • 二叉树(二)-二叉堆

    1.什么是二叉堆 二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树)。二叉堆有两种:...

  • PriorityQueue源码解析

    PriorityQueue 一个基于优先级堆的无界优先级队列。 二叉堆 可视化操作:二叉堆 二叉堆(The bin...

  • 数据结构(8) 二叉堆

    二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树)。 二叉堆实用数组来表示,存贮节点...

网友评论

      本文标题:二叉堆

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