JAVA集合排序算法之PriorityQueue堆排序

JAVA集合中存在大量常用数据结构及算法

如PriorityQueue堆排序

堆的两个特性
  • 完全二叉树
  • 堆中任一节点大于等于(大顶堆)(或小于等于(小顶堆))左右子节点
堆的存储

数组 可便捷的处理堆结构

在这里插入图片描述
如上图的堆用长度为9的数组表示,int[] heapArray = new int[9]
堆顶元素数组索引0,即heapArray[0]
给定索引 i,则左子节点索引:left = (i << 1) + 1,右子节点索引:right = left + 1,父节点索引:i >>> 1

PriorityQueue

PrioritQueue为小顶堆,即任一节点元素小于等于左右子节点,JDK源码定义部分:


    /**
     * Priority queue represented as a balanced binary heap: the two
     * children of queue[n] are queue[2*n+1] and queue[2*(n+1)].  The
     * priority queue is ordered by comparator, or by the elements'
     * natural ordering, if comparator is null: For each node n in the
     * heap and each descendant d of n, n <= d.  The element with the
     * lowest value is in queue[0], assuming the queue is nonempty.
     */
    private transient Object[] queue;

    /**
     * The number of elements in the priority queue.
     */
    private int size = 0;

    /**
     * The comparator, or null if priority queue uses elements'
     * natural ordering.
     */
    private final Comparator<? super E> comparator;
  • Object[] queue – 数组存储
  • size – 队列长度

插入元素:


    /**
     * Inserts the specified element into this priority queue.
     *
     * @return {@code true} (as specified by {@link Queue#offer})
     * @throws ClassCastException if the specified element cannot be
     *         compared with elements currently in this priority queue
     *         according to the priority queue's ordering
     * @throws NullPointerException if the specified element is null
     */
    public boolean offer(E e) {
        if (e == null)
            throw new NullPointerException();
        modCount++;
        int i = size;
        if (i >= queue.length)
            grow(i + 1);
        size = i + 1;
        //数组长度为0,即第1个元素直接存储到数组[]位置0
        if (i == 0)
            queue[0] = e;
        else
        //队列多于1个元素时,插入元素需进行堆化处理
            siftUp(i, e);
        return true;
    }

堆化:插入元素后仍然符合堆的特性

private void siftUp(int k, E x) {
        //如果指定了比较器Comparator,基于指定Comparator堆化,
        //如果未指定Comparator,基于元素自然顺序,即元素E需实现Comparator
        if (comparator != null)
            siftUpUsingComparator(k, x);
        else
            siftUpComparable(k, x);
    }

    //自底向上堆化
    private void siftUpComparable(int k, E x) {
        Comparable<? super E> key = (Comparable<? super E>) x;
        while (k > 0) {
            //父节点索引
            int parent = (k - 1) >>> 1;
            Object e = queue[parent];
            //新插入元素与父节点比较
            //若新插入元素大于等于父节点元素,则直接插入当前位置 k
            //否则,继续与父节点比较
            if (key.compareTo((E) e) >= 0)
                break;
            queue[k] = e;
            k = parent;
        }
        //插入新元素
        queue[k] = key;
    }

堆化示意图:
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值