优先级队列(堆)

堆: 堆逻辑上是一棵完全二叉树, 堆物理上是保存在数组中。满足任意结点的值都大于其子树中结点的值,叫做大堆,或者大根堆,或者最大堆。反之,则是小堆,或者小根堆,或者最小堆。
向下调整,向上调整,建堆,代码实现

public class lx {
    public static void adjustDown(int []array ,int size,int index){
        while (true){
            //左孩子的位置为index位置*2+1
        int leftChild=2*index+1;
        //判断是否为叶子节点 出口一
        if(leftChild>=size){
            return;
        }
        //找最小孩子
        int rightChild=leftChild+1;
        int minChild=leftChild;
        //比较左右孩子的元素大小 小的放进minChild中
        if(rightChild<size&&array[rightChild]<array[leftChild]){
            minChild=rightChild;
        }
        //比较最小孩子(minChild)与index位置的值
        if (array[index] <= array[minChild]) {
            return;
        }
        // 4.程序 走到这说明不满足堆的性质  进行交换将index位置元素与minIndex位置的元素进行交换
        int t = array[index];
        array[index] = array[minChild];
        array[minChild] = t;

        // 5.循环 把最小的孩子视为 index,继续循环直到index位置满足堆的性质
        index = minChild;
    }
  }
   public static void adjustUp(int []array ,int size ,int index){
        while (true){
            // 出口 index位置为根位置
            if(index==0){
                break;
            }
            //找到Index位置的父亲位置 parentIndex
            int parentIndex=(index-1)/2;
            //出口 满足堆的性质 父亲的值小于左右孩子
            if(array[parentIndex]<array[index]){
                break;
            }
            // 不满足 交换index位置与parentIndex位置上的元素
            int t=array[parentIndex];
            array[parentIndex]=array[index];
            array[index]=t;
        }
   }
   public static void createHeap(int []array, int size){
        //找到层序遍历最后一个结点的下标
       int lastIndex=size-1;
       //找到最后一个结点父节点下标
       int parentIndex=lastIndex-1/2;
       for (int i = parentIndex; i >=0; i--) {
           adjustDown(array,size,i);
       }
   }
}

我自己实现的优先级队列(堆)add()remove() element() 方法 (以小堆为例) 需要注意的是:当进行add时要进行向上调整(adjust up)当进行remove时要删除优先级队列中第一个元素 并且把最后一个元素放到第一个元素上,然后在进行向下调整(adjust down)

优先级队列(堆):可以找出数组中最大值(大堆),最小值(小堆)

public class MyPriorityQueue {
    private Integer[] array;
    private int size;
    public MyPriorityQueue(){
        array=new Integer[100];
        size=0;
    }
    public Integer element(){
        if(size==0){
            throw new RuntimeException("空了");
        }
        return array[0];
    }
    public Integer remove(){
        if(size==0){
            throw new RuntimeException("空了");
        }
        int e=array[0];
        array[0]=array[size-1];
        size--;
        adjustDown(0);
        return e;
    }
    public void add(Integer e){
        array[size]=e;
        size++;
        adjustUp(size-1);
    }

    private void adjustDown(int index) {
        while (true) {
            int leftChildIndex = 2 * index + 1;
            if (leftChildIndex >= size) {
                return;
            }
            int rightChildIndex = leftChildIndex + 1;
            int minChildIndex = leftChildIndex;
            if (rightChildIndex < size && array[rightChildIndex] < array[leftChildIndex]) {
                minChildIndex = rightChildIndex;
            }
            if (array[index] <= array[minChildIndex]) {
                return;
            }
            int t = array[minChildIndex];
            array[minChildIndex] = array[index];
            array[index] = t;
            index = minChildIndex;
        }
    }
    private void adjustUp(int index){
        while (true){
            if(index==0){
                return;
            }
            //找到Index位置的父亲位置 parentIndex
            int parentIndex=(index-1)/2;
            //出口 满足堆的性质 父亲的值小于左右孩子
            if(array[parentIndex]<array[index]){
                break;
            }
            // 不满足 交换index位置与parentIndex位置上的元素
            int t=array[parentIndex];
            array[parentIndex]=array[index];
            array[index]=t;
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值