PriorityQueue--优先级队列

来源:互联网 发布:矩阵内积 编辑:程序博客网 时间:2024/05/17 06:56

      优先级队列内部维护的是一个二叉堆,通过阅读代码可以发现最主要的操作就是remove操作,当删除一个元素时,有可能破坏了小顶堆的特性,需要重建堆,然后重建堆的操作便是构成堆排序(注意堆排序使用的是大顶堆特性)的基础。所以掌握了优先级队列的二叉堆实现,便掌握了堆排序,反之亦然。

package changsheng.algorithms.heap;// PriorityQueue interface//// ******************PUBLIC OPERATIONS*********************// void insert( x )   --> Insert x// Comparable deleteMin( )--> Return and remove smallest item// Comparable findMin( )  --> Return smallest item// boolean isEmpty( )     --> Return true if empty; else false// void makeEmpty( )      --> Remove all items// int size( )            --> Return size// ******************ERRORS********************************// Throws UnderflowException for findMin and deleteMin when emptypublic interface PriorityQueue<E extends Comparable<? super E>>{        /**     * Insert into the priority queue, maintaining heap order.     * Duplicates are allowed.     * @param x the item to insert.     */    void insert( E x );    /**     * Find the smallest item in the priority queue.     * @return the smallest item.     * @throws UnderflowException if empty.     */    E findMin( );    /**     * Remove the smallest item from the priority queue.     * @return the smallest item.     * @throws UnderflowException if empty.     */    E deleteMin( );    /**     * Test if the priority queue is logically empty.     * @return true if empty, false otherwise.     */    boolean isEmpty( );    /**     * Make the priority queue logically empty.     */    void makeEmpty( );        /**     * Returns the size.     * @return current size.     */    int size( ); }
package changsheng.algorithms.heap;import java.util.Arrays;import changsheng.algorithms.util.EmptyQueueException;import changsheng.algorithms.util.Swap;public class DefaultPriorityQueue<E extends Comparable<? super E>> implementsPriorityQueue<E> {private E[] array;private int DEFAULT_SIZE = 10;private int currentSize = 0;public DefaultPriorityQueue() {makeEmpty();}/** * Construct the binary heap from an array. *  * @param items *            the inital items in the binary heap. */@SuppressWarnings("unchecked")public DefaultPriorityQueue(E[] items) {currentSize = items.length;array = (E[]) new Comparable[items.length + 1];for (int i = 0; i < items.length; i++)array[i + 1] = items[i];BuildMaxHeap();}@Overridepublic void insert(E x) {if ((currentSize + 1) == array.length) {allocateArray(array.length * 2);}int hole = ++currentSize;array[0] = x;while (x.compareTo(array[hole / 2]) < 0) {array[hole] = array[hole / 2];hole /= 2;}array[hole] = x;}private void allocateArray(int size) {array = Arrays.copyOf(array, size);}@Overridepublic E findMin() {if (isEmpty()) {throw new EmptyQueueException("Empty binary heap !");}return array[1];}@Overridepublic E deleteMin() {if (isEmpty()) {throw new EmptyQueueException("Empty binary heap !");}E min = findMin();array[1] = array[currentSize--];MaxHeapify(1);return min;}/** * 建堆时必须自底向上建立 */private void BuildMaxHeap() {int len = array.length;for (int i = len / 2; i >= 1; i--) {MaxHeapify(i);}}/* * 递归调用 */private void MaxHeapify(int i) {/** * 在i(节点)、2*i(左孩子)和2*i+1(右孩子)中选出一个最小索引smallest。 如果smallest == i * 说明已满足小顶堆的特性,退出递归调用。 如果smallest != i * 说明三者不满足小顶堆的特性,将smallest与i位置上的值进行交换。 然后再以smallest为参数进行MaxHeapify调用。 */int left = 2 * i;int right = 2 * i + 1;int smallest = i;if (left <= currentSize && array[left].compareTo(array[smallest]) < 0) {smallest = left;}if (right <= currentSize && array[right].compareTo(array[smallest]) < 0) {smallest = right;}if (smallest != i) {Swap.swap(array, i, smallest);MaxHeapify(smallest);}}/** * 非递归调用 */@SuppressWarnings("unused")private void MaxHeapifyNormal(int hole) {int child;E tmp = array[hole];for (; hole * 2 <= currentSize; hole = child) {child = hole * 2;if (child != currentSize&& array[child + 1].compareTo(array[child]) < 0)child++;if (array[child].compareTo(tmp) < 0)array[hole] = array[child];elsebreak;}array[hole] = tmp;}@Overridepublic boolean isEmpty() {return currentSize == 0;}@SuppressWarnings("unchecked")@Overridepublic void makeEmpty() {array = (E[]) new Comparable[DEFAULT_SIZE];currentSize = 0;}@Overridepublic int size() {return currentSize;}public static void main(String[] args) {int numItems = 10000;DefaultPriorityQueue<Integer> h1 = new DefaultPriorityQueue<Integer>();Integer[] items = new Integer[numItems - 1];int i = 37;int j;for (i = 37, j = 0; i != 0; i = (i + 37) % numItems, j++) {h1.insert(i);items[j] = i;}for (i = 1; i < numItems; i++)if (h1.deleteMin() != i)System.out.println("Oops! " + i);}}


原创粉丝点击