zoukankan      html  css  js  c++  java
  • 堆(优先队列)

    二叉堆

    二叉堆常常用于优先队列的实现。

    堆是一个被完全填满的二叉树,有可能的例外是在底层,底层上的元素从左到右填入。

    因为二叉堆是完全二叉树,所以可以使用数组表示,而不需要使用链表。(使用链表似乎代码实现方便点)

    堆序性质

    任意节点的值都小于它所有字节点的值

    代码实现

    /**
     * 二叉堆
     * 将堆数据存放在数组内,对自上而下,自左而右的数据依次放到数组中,数组索引从1开始,即array[0]不存放数据
     */
    public class BinaryHeap {
        public BinaryHeap(){}
    
        public BinaryHeap(int x){
            currentSize++;
            array[currentSize]=x;
        }
    
        public BinaryHeap(int[] items){
            currentSize=items.length;
            array = new int[(currentSize+2)*11/10];
            int i=1;
            for(int item:items){
                array[i++]=item;
            }
            buildHeap();
        }
    
        public void insert(int x){
            if(currentSize==array.length-1) enlargeHeap(array.length*2+1);
            //hole代表空穴的位置
            int hole = ++currentSize;
            //空穴的位置上浮
            for(;hole>1 && x<(array[hole/2]);hole/=2){
                array[hole]=array[hole/2];
            }
            //最后空穴的位置为hole
            //将x放入空穴
            array[hole]=x;
        }
    
        public int findMin() throws Exception{
            if(isEmpty()) throw new Exception("堆为空");
            return array[1];
        }
    
        public int deleteMin()throws Exception{
            if(isEmpty()) throw new Exception("无法对空堆作删除操作");
            int min = findMin();
            //把最后一个元素放在首位,并减小堆大小currentSize
            array[1]=array[currentSize--];
            //然后调整堆第一个元素的位置
            percolateDown(1);
            return min;
        }
    
        public boolean isEmpty(){
            return currentSize==0;
        }
    
        public void makeEmpty(){
            currentSize=0;
        }
    
        private static final int DEFAULT_CAPCITY=10;
    
        private int currentSize=0;
        private int[] array;
    
        //对hole位置的元素做下沉操作
        private void percolateDown(int hole){
            int child=0;
            int tmp = array[hole];
            for(;hole*2<=currentSize;hole=child){
                child=hole*2;
                if(child!=currentSize && array[child+1]<array[child]) child++;
                if(array[child]<tmp) array[hole]=array[child];
                else break;
            }
            array[hole]=tmp;
        }
    
        private void buildHeap(){
            for (int i=currentSize/2;i>0;i--){
                percolateDown(i);
            }
        }
    
        private void enlargeHeap(int newSize){
            if(newSize<=array.length) return;
            int[] tmp = new int[newSize];
            for(int i=1;i<=currentSize;i++){
                tmp[i]=array[i];
            }
            array=tmp;
        }
    }
    
  • 相关阅读:
    leetcode刷题笔记303题 区域和检索
    leetcode刷题笔记301题 删除无效的括号
    20201208日报
    20201118日报
    20201117日报
    20201116日报
    20201115日报
    20201114日报
    20201113日报
    20201112日报
  • 原文地址:https://www.cnblogs.com/wuchaodzxx/p/6811888.html
Copyright © 2011-2022 走看看