PriorityQueue--优先级队列

      优先级队列内部维护的是一个二叉堆,通过阅读代码可以发现最主要的操作就是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 empty

public 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>> implements
		PriorityQueue<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();
	}

	@Override
	public 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);
	}

	@Override
	public E findMin() {
		if (isEmpty()) {
			throw new EmptyQueueException("Empty binary heap !");
		}
		return array[1];
	}

	@Override
	public 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];
			else
				break;
		}
		array[hole] = tmp;
	}

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

	@SuppressWarnings("unchecked")
	@Override
	public void makeEmpty() {
		array = (E[]) new Comparable[DEFAULT_SIZE];
		currentSize = 0;
	}

	@Override
	public 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);
	}

}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值