个人学习笔记:堆的实现(java数组实现)

4 篇文章 0 订阅
2 篇文章 0 订阅
1、自定义实现:

(1)自定义的堆接口:

/**
 * 元素为int类型的堆的接口
 */
public interface Heap {
    /**
     * 当堆为空时返回true
     * @return
     */
    boolean isEmpty();

    /**
     * 堆的元素个数
     * @return
     */
    int size();

    /**
     * 返回堆的根节点并将其从堆中删除
     * @return
     */
    int poll();

    /**
     * 返回堆的根节点元素但不删除
     * @return
     */
    int peek();

    /**
     * 向堆中添加一个元素,当堆已满时会返回false,此时无法再插入元素
     * @param element
     * @return
     */
    boolean add(int element);
}

(2)自定义的小根堆实现:

/**
 * 小根堆,即其根节点元素的值小于其子节点元素的值
 */
public class MinHeap implements Heap{
    private int capacity;//堆的容量(能存储的最大元素个数)
    private int heapSize;//堆中的元素个数
    private int[] heap;//存储元素的小根堆

    /**
     * 构造函数,初始化堆的容量,默认容量设置为16
     */
    public MinHeap() {
        this.capacity = 16;
        heap=new int[capacity+1];
    }

    /**
     * 构造函数,初始化堆的容量
     * @param capacity
     */
    public MinHeap(int capacity) {
        this.capacity = capacity;
        heap=new int[capacity+1];
    }


    @Override
    public boolean isEmpty() {
        return (heapSize==0);
    }

    @Override
    public int size() {
        return heapSize;
    }

    @Override
    public int poll() {
        if(heapSize==0)
            throw new RuntimeException("堆为空");

        int result=heap[1];//保存根节点的值

        //获取到最后一个叶子结点
        int latElement=heap[heapSize--];
        //将最后一个叶子节点放在根节点上
        heap[1]=latElement;

        int currentNode=1;//从根节点开始向下遍历,将根节点放在合适的位置上。
        int child=2;//当前节点的子节点

        while (child<=heapSize){
            //heap[child]应该是较小的孩子
            if(child<heapSize&&heap[child]>heap[child+1])
                child++;
            //已经找到了合适的插入位置
            if(latElement<heap[child])
                break;
            //继续向下移动寻找位置
            heap[currentNode]=heap[child];
            currentNode=child;
            child*=2;
        }

        heap[currentNode]=latElement;

        return result;
    }

    @Override
    public int peek() {
        if(heapSize==0)
            throw new RuntimeException("堆为空");
        return heap[1];
    }

    @Override
    public boolean add(int element) {
        //堆已满
        if (heapSize ==capacity)
            return false;

        int currentNode=++heapSize;//当前节点的索引
        //从新叶子开始向上查找合适的位置将新节点插入
        while (currentNode!=1&&heap[currentNode/2]>element){
            heap[currentNode]=heap[currentNode/2];
            currentNode/=2;
        }
        heap[currentNode]=element;
        return true;
    }

}

(3)自定义的大根堆实现:

/**
 * 大根堆,即其根节点元素的值大于其子节点元素的值
 */
public class MaxHeap implements Heap{

    private int capacity;//堆的容量(能存储的最大元素个数)
    private int heapSize;//堆中的元素个数
    private int[] heap;//存储元素的大根堆

    /**
     * 构造函数,初始化堆的容量,默认容量设置为16
     */
    public MaxHeap() {
        this.capacity = 16;
        heap=new int[capacity+1];
    }

    /**
     * 构造函数,初始化堆的容量
     * @param capacity
     */
    public MaxHeap(int capacity) {
        this.capacity = capacity;
        heap=new int[capacity+1];
    }

    @Override
    public boolean isEmpty() {
        return (heapSize==0);
    }

    @Override
    public int size() {
        return heapSize;
    }

    @Override
    public int poll() {
        if(heapSize==0)
            throw new RuntimeException("堆为空");
        int result=heap[1];//保存根节点的值
        //获取到最后一个叶子结点
        int latElement=heap[heapSize--];
        //将最后一个叶子节点放在根节点上
        heap[1]=latElement;

        int currentNode=1;//从根节点开始向下遍历,将根节点放在合适的位置上。
        int child=2;//当前节点的子节点

        while (child<=heapSize){
            //heap[child]应该是较大的孩子
            if(child<heapSize&&heap[child]<heap[child+1])
                child++;
            //已经找到了合适的插入位置
            if(latElement>=heap[child])
                break;
            //继续向下移动寻找位置
            heap[currentNode]=heap[child];
            currentNode=child;
            child*=2;
        }

        heap[currentNode]=latElement;

        return result;
    }

    @Override
    public int peek() {
        if(heapSize==0)
            throw new RuntimeException("堆为空");
        return heap[1];
    }

    @Override
    public boolean add(int element) {
        //堆已满
        if (heapSize==capacity)
            return false;
        int currentNode=++heapSize;//当前节点的索引
        //从新叶子开始向上查找合适的位置将新节点插入
        while (currentNode!=1&&heap[currentNode/2]<element){
            heap[currentNode]=heap[currentNode/2];
            currentNode/=2;
        }
        heap[currentNode]=element;
        return true;
    }
}
2、java jdk中的堆:

通过使用jdk自带的PriorityQueue类,当调用不带参数的构造函数时,堆的默认容量为11(可通过调用带参数的构造函数创建堆来指定堆的容量)。
(1)小根堆:

PriorityQueue<Integer> minHeap=new PriorityQueue<>();
//

(2)大根堆:(在小根堆的基础上重写Comparator中的compare函数)

PriorityQueue<Integer> maxHeap=new PriorityQueue<Integer>(new Comparator<Integer>(){
	  @Override
	  public int compare(Integer o1, Integer o2) {
	      return o2-o1;
	  }
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值