优先队列

原创 2015年07月07日 21:33:46

完全二叉树

同时满足已下条件的二叉树是完全二叉树:
* 除最后一层外,每层的结点都有左右两个结点
* 最后一层的结点从左向右,紧密排列,中间没有空隙

例如下图就是一颗完全二叉树
一颗完全二叉树

所有父结点都大(小)于子结点的完全二叉树叫做最大(小)堆。上图就是一个最大堆。

堆能做什么

  • 移除最值
  • 吸纳新值

对应接口:
public void add(E item);
public E remove();
public E peek();
public int size();
public boolean isEmpty();

接口代码

public interface IPQ<E> {
    /**
     * 把<code>item<code>加入到队列中
     * 
     * @param item
     *            要添加的元素
     */
    public void add(E item);

    /**
     * 移除最值
     * 
     * @return
     */
    public E remove();

    /**
     * 查询最值
     * 
     * @return 最值
     */
    public E peek();

    /**
     * 返回队列中元素的个数
     * 
     * @return 队列大小
     */
    public int size();

    /**
     * 查询队列是否为空
     * 
     * @return <code>true</code> 如果队列中元素个数为0;否则,返回<code>false</code>。
     */
    public boolean isEmpty();
}

实现代码

package com.gmail.dailyefforts.ds;

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;

import com.gmail.dailyefforts.princeton.stdlib.In;

public class PQ<E extends Comparable<? super E>> implements IPQ<E> {

    private transient E[] a;
    private transient int size;
    private final Order order;

    public enum Order {
        ASC, DESC
    }

    public PQ(int capacity, Order order) {
        this.a = (E[]) new Comparable[capacity + 1];
        this.size = 0;
        this.order = order;
    }

    @Override
    public void add(E item) {
        if (size >= a.length - 1) {
            resize(size << 1);
        }
        a[++size] = item;
        siftUp(size);
    }

    private void siftUp(int i) {
        while (i > 1) {
            final int parentIdx = i >>> 1;
            if (greater(parentIdx, i)) {
                swap(parentIdx, i);
            }
            i = parentIdx;
        }
    }

    private boolean greater(int i, int j) {
        // final Comparable<? super E> key = (Comparable<? super E>) a[i];
        final boolean greater = a[i].compareTo(a[j]) > 0;
        if (Order.DESC.equals(this.order)) {
            return !greater;
        }
        return greater;
    }

    private void swap(int i, int j) {
        final E tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }

    private void resize(int capacity) {
        final E[] tmp = (E[]) new Comparable[capacity];
        for (int i = 1; i <= size; i++) {
            tmp[i] = a[i];
        }
        a = tmp;
    }

    @Override
    public E remove() {
        if (isEmpty()) {
            return null;
        }
        E max = a[1];
        int N = size;
        // move the last item to a[1]
        a[1] = a[N];
        size--;
        siftDown(1);
        a[N] = null;
        return max;
    }

    @Override
    public E peek() {
        return a[0];
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public String toString() {
        final StringBuilder builder = new StringBuilder();
        builder.append('[');
        for (int i = 1; i <= size; i++) {
            builder.append(a[i]);
            if (i < size) {
                builder.append(", ");
            }
        }
        builder.append(']');
        return builder.toString();
    }

    private void siftDown(int i) {
        while ((i << 1) <= size) {
            // has child
            final int left = i << 1;
            int k = left;
            if (left < size && greater(left, left + 1)) {
                k++;
            }
            if (greater(k, i)) {
                break;
            }
            swap(i, k);
            i = k;
        }
    }

    public static void main(String[] args) {
        final int N = 100 * 100;
        PQ<Integer> pq = new PQ<>(N, Order.DESC);
        MyComparator comparator = new MyComparator();
        Queue<Integer> q = new PriorityQueue<>(N, comparator);
        Random random = new Random();
        for (int i = 0; i < N; i++) {
            int val = random.nextInt(N);
            pq.add(val);
            q.add(val);
        }
        assert (pq.size() == q.size());
        while (!pq.isEmpty()) {
            final int a = pq.remove();
            final int b = q.remove();
            System.out.println(a);
            assert (a == b);
        }
        System.out.println(pq.size());
    }

}

class MyComparator<E extends Comparable<E>> implements Comparator<E> {
    @Override
    public int compare(E o1, E o2) {
        return o2.compareTo(o1);
    }

}

相关文章推荐

优先队列操作

  • 2013年04月12日 15:59
  • 3KB
  • 下载

关于STL中优先队列的用法

  • 2010年01月02日 12:20
  • 2KB
  • 下载

C++ STL优先队列常用用法

STL优先队列

poj 1442(两个优先队列)

Black Box Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6109   Accepted: 2476 ...

C-优先队列

  • 2016年12月08日 21:08
  • 5KB
  • 下载

字典树KMP优先队列

  • 2015年03月17日 21:46
  • 1.03MB
  • 下载

Black Box——优先队列

Black Box Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit St...

1464堆优先队列

  • 2014年08月17日 20:37
  • 2KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:优先队列
举报原因:
原因补充:

(最多只允许输入30个字)