优先队列

优先队列:

优先队列是最少拥有两种操作(插入和删除最小值)实现的数据结构。

实现优先队列并不难,我相信只要是有点计算机基础的人都能想到一些方法,比如:时刻保持一个有序队列,或者每次遍历一个队列直到找出最小值为止,或者更高级点的那就是使用二叉查找树。但是无论是从时间/空间复杂度还是从代码复杂度来讲,以上三种都不是实现优先队列的最好选择。

堆:

就现在来讲,对于优先队列的实现方法中,使用最普遍的还是一种叫做堆的工具!

堆说白了其实就是一颗完全二叉树,但相比于完全二叉树,堆又有着结构性和堆序性两个性质。

完全二叉树的重要规律:

在用数组实现完全二叉树时,对于数组中的任意位置i,其左儿子在2i位置上,右儿子在2i+1位置上,它的父亲则在i/2的位置上,记住这个规律,这对于堆的实现时直观重要的。

代码实现:

bean对象:

public class Node<T> implements Comparable<T>{

    private T data;

    public Node(T data){
        this.data = data;
    }
    
    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    @Override
    public int compareTo(T o) {
        if (o instanceof Integer && data instanceof Integer){
            Integer integer1 = (Integer)data;
            Integer integer2 = (Integer)o;
            return integer1-integer2;
        }else {
            throw new RuntimeException("params not Integer");
        }
    }
}

堆实现:

public class BinaryHeap<T> implements TreeService<T> {

    private Node<T>[] array;

    private int size = 11;

    private int currentSize = 0;

    public BinaryHeap(){
        array = new Node[size];
    }

    public BinaryHeap (int size){
        this.size = size;
        array = new Node[size+1];

    }

    public BinaryHeap(Collection collection){
        array = new Node[collection.size()+1];
        for (Object o : collection) {
            array[++currentSize] = new Node<>((T) o);
        }
        for (int hole=currentSize/2;hole>0;hole--){
            System.out.println(hole);
            fliterDown(hole);
        }
        System.out.println("---------");
    }

    /**
     * 上虑插入
     * @param o
     */
    @Override
    public void insert(T o) {
        if (isEmpty()){
            array[1] = new Node<T>(o);
        }else if (isFull()) {
            throw new RuntimeException("Heap is Full");
        }else {
                int tail = currentSize+1;
                //注意完全二叉树性质
                for (array[0]=new Node<>(o); array[tail/2].compareTo(o) > 0 ; tail/=2) {
                    //如果父节点数据大于待插入数据
                    array[tail] = array[tail/2];
                }
                array[tail] = new Node<T>(o);
            }
        currentSize++;
    }

    /**
     * 删除最小值
     * 删除方法:移除根节点中
     */
    public T deleteMin(){
         if (isEmpty()) {
             throw new RuntimeException("Heap is empty");
         }
         Node min = array[1];
         array[1] = array[currentSize--];
         fliterDown(1);
         return (T) min.getData();
    }

    private void fliterDown(int hole){
        T tail = array[hole].getData();
        int child;
        for (;2*hole <= currentSize;hole=child){
            child = 2 * hole;
            //如果child不等于当前size则代表当前节点有两个子节点
            if (child!=currentSize&&array[child].compareTo(array[child+1].getData())>0){
                child++;
            }
            if (array[child].compareTo(tail)<0){
                array[hole]=array[child];
            }else {
                break;
            }
        }
        array[hole]=new Node<>(tail);
    }

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

    @Override
    public boolean isFull() {
        return currentSize==size;
    }

    @Override
    public Node<T>[] getArray() {
        return array;
    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值