数据结构之堆

堆的定义:堆是计算机中一种特殊的数据结构的统称,通常是一个可以看做一棵树的数组对象。堆总是满足下列性质:

  1. 堆中某个节点的值总是总大于或者不小于其父节点的值;
  2. 堆总是一颗完全二叉树。

将根节点最大的堆叫做最大堆或者大根堆,根节点最小的堆叫做最小堆或者小根堆。常见的堆有二叉堆,斐波那契堆。

二叉堆

二叉堆是一种特殊的堆,二叉堆是完全二叉树或者近似完全二叉堆。二叉堆有两种:最大堆和最小堆。最大堆:父节点的值总是大于或者等于子节点的值;最小堆:父节点的值总是小于或者等于子节点的值。二叉堆有两个性质,即结构性和堆序性。

  • 结构性质:一颗高为h的完全二叉树有2^{h}2^{h+1}-1个节点。所以完全二叉树的高为logN,显然它是O(logn)。因为完全二叉树这么有规律,所以它可以用一个数组表示而不需要使用链。

  • 堆序性质:在一个堆中,对于每一个节点X,X的父亲中的关键字小于(或等于)X中的关键字,根节点除外(它没有父亲)。

基本堆操作

基本操作包括插入、删除、构建。下面代码演示:

package structures;

import java.util.EmptyStackException;

/**
 * 二叉堆的性质
 * @param <AnyType>
 */
public class BinaryHeap<AnyType extends Comparable<? super AnyType>> {
    private static final int DEFAULT_CAPACITY = 10;
    //number of element in heap
    private int currentSize;
    private AnyType [] array;

    public BinaryHeap(AnyType[] items) {
        //this.array = array;
        currentSize = array.length;
        this.array = (AnyType[]) new Comparable[(currentSize+2)*11/10];
        int i = 1;
        for (AnyType item:items) {
            array[i++] = item;
        }
        buildHeap();
    }

    /**
     * 构建符合堆条件的数组
     */
    private void buildHeap() {
        for (int i=currentSize/2;i>0;i--){
            percolateDown(i);
        }
    }

    /**
     * 插入操作
     * @param x
     */
    public void insert(AnyType x){
        if(currentSize==array.length-1){
            enlargeArray(array.length*2+1);
        }

        int hole =++currentSize;
        for(array[0]=x;x.compareTo(array[hole/2])<0;hole/=2){
            array[hole] = array[hole/2];
        }
        array[hole]=x;
    }

    /**
     * 取得最小的值
     * @return
     */
    public AnyType deleteMin(){
        if(isEmpty()){
            throw new EmptyStackException();
        }

        AnyType minItem = findMin();
        array[1] = array[currentSize--];
        percolateDown(1);

        return minItem;
    }

    /**
     * 重新构建数组,使数组符合二叉堆结构
     */
    private void percolateDown(int num) {
        int child = 0;
        AnyType tmp = array[num];

        for (;num*2<=currentSize;num=child){
            child = num * 2;
            if(child!=currentSize&&array[child+1].compareTo(array[child])<0){
                child++;

            }
            if(array[child].compareTo(tmp)<0){
                array[num] = array[child];
            }else{
                break;
            }
        }
        array[num] = tmp;
    }

    /**
     * 寻找最小值
     * @return
     */
    private AnyType findMin() {
    }

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

        return false;
    }

    /**
     * 对数组扩容
     * @param i
     */
    private void enlargeArray(int i) {
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值