堆的创建与增删查改

本文介绍了Java中的优先级队列及其底层基于堆的数据结构,详细讲解了堆的创建、调整方法,以及堆的插入、删除操作,特别关注了建堆和调整的时间复杂度。
摘要由CSDN通过智能技术生成

一、优先级队列

        优先级队列(Priority Queue)是一种出元素具有优先级的队列,例如在出队的时候元素需要出优先级更高的元素。

        Java中,优先级队列的底层是通过堆来实现的。

二、堆

        堆是一棵特殊的完全二叉树,他的父节点总是大于等于子节点(大根堆) 或者 父节点总是小于等于子节点(小根堆)。

        下面我们以大根堆为例来介绍堆的基本操作

三、堆的创建

        由于堆是一课完全二叉树,所以适合用顺序存储的方式来存储

        

    public int[] elem;
    public int usedSize;

    public PriorityQueue(int[] elem) {
        this.elem = elem;
        usedSize += elem.length;
    }

    3.1 向下调整

        

        我们使用向下调整的方式使这个树变成大根堆,即从根节点开始,依次将每个节点和它的子树变成大根堆。

public void createBigHeap() {
        for (int parent = (usedSize-1-1)/2; parent >= 0; parent--) {
            siftDown(parent, usedSize);
        }
    }

    //向下调整
    private void siftDown(int parent,int end) {
        int child = 2*parent+1;
        while (child < end) {
            if(child + 1 < usedSize && elem[child] < elem[child+1]) {
                child++;
            }
            //child一定是 左右孩子最大值的下标
            if(elem[child] > elem[parent]) {
                //交换
                swap(child,parent);
                parent = child;
                child = 2*parent+1;
            }else {
                break;
            }
        }
    }

    3.2 建堆的时间复杂度

                建堆的时间复杂度为O(N)。

四、堆的插入与删除

     4.1 堆的插入

               先将待插入元素放入队列末尾元素的后一个位置,如果空间不够需要扩容。然后使用向上调整来保持堆为大根堆。

      4.2 向上调整

                

private void shiftUp(int child) {
        int parent = (child-1)/2;
        while (child > 0) {
            if(elem[child] > elem[parent]) {
                swap(child,parent);
                child = parent;
                parent = (child-1)/2;
            }else {
                break;
            }
        }
    }

     4.3堆的删除

                堆的删除一定是只能删除堆顶元素,我们采取将末尾元素与堆顶元素互换的思路,然后useSize--,再进行向下调整。

        

 public int poll() {
        int tmp = elem[0];
        swap(0,usedSize-1);
        usedSize--;
        siftDown(0,usedSize);
        return tmp;
    }

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值