《漫画算法》源码整理-4 大顶堆 小顶堆 优先队列

Posted GarfieldEr007

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《漫画算法》源码整理-4 大顶堆 小顶堆 优先队列相关的知识,希望对你有一定的参考价值。

堆操作

import java.util.Arrays;

public class HeapOperator 

    /**
     * 上浮调整
     * @param array     待调整的堆
     */
    public static void upAdjust(int[] array) 
        int childIndex = array.length-1;
        int parentIndex = (childIndex-1)/2;
        // temp保存插入的叶子节点值,用于最后的赋值
        int temp = array[childIndex];
        while (childIndex > 0 && temp < array[parentIndex])
        
            //无需真正交换,单向赋值即可
            array[childIndex] = array[parentIndex];
            childIndex = parentIndex;
            parentIndex = (parentIndex-1) / 2;
        
        array[childIndex] = temp;
    

    /**
     * 下沉调整
     * @param array     待调整的堆
     * @param parentIndex    要下沉的父节点
     * @param length    堆的有效大小
     */
    public static void downAdjust(int[] array, int parentIndex, int length) 
        // temp保存父节点值,用于最后的赋值
        int temp = array[parentIndex];
        int childIndex = 2 * parentIndex + 1;
        while (childIndex < length) 
            // 如果有右孩子,且右孩子小于左孩子的值,则定位到右孩子
            if (childIndex + 1 < length && array[childIndex + 1] < array[childIndex]) 
                childIndex++;
            
            // 如果父节点小于任何一个孩子的值,直接跳出
            if (temp <= array[childIndex])
                break;
            //无需真正交换,单向赋值即可
            array[parentIndex] = array[childIndex];
            parentIndex = childIndex;
            childIndex = 2 * childIndex + 1;
        
        array[parentIndex] = temp;
    

    /**
     * 构建堆
     * @param array     待调整的堆
     */
    public static void buildHeap(int[] array) 
        // 从最后一个非叶子节点开始,依次下沉调整
        for (int i = (array.length-2)/2; i >= 0; i--) 
            downAdjust(array, i, array.length);
        
    

    public static void main(String[] args) 
        int[] array = new int[] 1,3,2,6,5,7,8,9,10,0;
        upAdjust(array);
        System.out.println(Arrays.toString(array));

        array = new int[] 7,1,3,10,5,2,8,9,6;
        buildHeap(array);
        System.out.println(Arrays.toString(array));
    

优先队列

import java.util.Arrays;

public class PriorityQueue 

    private int[] array;
    private int size;

    public PriorityQueue()
        //队列初始长度32
        array = new int[32];
    

    /**
     * 入队
     * @param key  入队元素
     */
    public void enQueue(int key) 
        //队列长度超出范围,扩容
        if(size >= array.length)
            resize();
        
        array[size++] = key;
        upAdjust();
    

    /**
     * 出队
     */
    public int deQueue() throws Exception 
        if(size <= 0)
            throw new Exception("the queue is empty !");
        
        //获取堆顶元素
        int head = array[0];
        //最后一个元素移动到堆顶
        array[0] = array[--size];
        downAdjust();
        return head;
    

    /**
     * 上浮调整
     */
    private void upAdjust() 
        int childIndex = size-1;
        int parentIndex = (childIndex-1)/2;
        // temp保存插入的叶子节点值,用于最后的赋值
        int temp = array[childIndex];
        while (childIndex > 0 && temp > array[parentIndex])
        
            //无需真正交换,单向赋值即可
            array[childIndex] = array[parentIndex];
            childIndex = parentIndex;
            parentIndex = (parentIndex-1) / 2;
        
        array[childIndex] = temp;
    

    /**
     * 下沉调整
     */
    private void downAdjust() 
        // temp保存父节点值,用于最后的赋值
        int parentIndex = 0;
        int temp = array[parentIndex];
        int childIndex = 1;
        while (childIndex < size) 
            // 如果有右孩子,且右孩子大于左孩子的值,则定位到右孩子
            if (childIndex + 1 < size && array[childIndex + 1] > array[childIndex]) 
                childIndex++;
            
            // 如果父节点大于任何一个孩子的值,直接跳出
            if (temp >= array[childIndex])
                break;
            //无需真正交换,单向赋值即可
            array[parentIndex] = array[childIndex];
            parentIndex = childIndex;
            childIndex = 2 * childIndex + 1;
        
        array[parentIndex] = temp;
    

    /**
     * 队列扩容
     */
    private void resize() 
        //队列容量翻倍
        int newSize = this.size * 2;
        this.array = Arrays.copyOf(this.array, newSize);
    

    public static void main(String[] args) throws Exception 
        PriorityQueue priorityQueue = new PriorityQueue();
        priorityQueue.enQueue(3);
        priorityQueue.enQueue(5);
        priorityQueue.enQueue(10);
        priorityQueue.enQueue(2);
        priorityQueue.enQueue(7);
        System.out.println("出队元素:" + priorityQueue.deQueue());
        System.out.println("出队元素:" + priorityQueue.deQueue());
    

以上是关于《漫画算法》源码整理-4 大顶堆 小顶堆 优先队列的主要内容,如果未能解决你的问题,请参考以下文章

堆排序

python数据结构_大顶堆和小顶堆

295. 数据流的中位数

优先队列

[剑指offer] 41. 数据流中的中位数 (大小堆,优先队列)

构建大小顶堆