import java.util.EmptyStackException; /** * Introduction to Algorithms, Second Edition * 6.4 Priority queues * * @author 土豆爸爸 * */ public class PriorityQueue<KeyType extends Comparable<KeyType>, T extends IPriorityQueueElement<KeyType>> { T[] array; int heapSize; /** * 构造函数 * @param size 初始数组大小 */ @SuppressWarnings("unchecked") public PriorityQueue(int size) { array = (T[]) new IPriorityQueueElement[size]; } /** * 获取当前heap中的最大值 * * @return 最大值 */ public T maximum() { return array[0]; } /** * 获取当前heap中的最大值,并从heap中删除最大值 * @return 最大值 */ public T extractMax() { if (heapSize < 1) { throw new EmptyStackException(); } T max = array[0]; array[0] = array[heapSize - 1]; heapSize--; maxHeapify(0); return max; } /** * 插入一个元素 * @param e */ @SuppressWarnings("unchecked") public void insert(T e) { if (heapSize == array.length) { T[] newArray = (T[]) new IPriorityQueueElement[array.length * 2]; System.arraycopy(array, 0, newArray, 0, array.length); array = newArray; } int i = heapSize++; array[i] = e; int p = parent(i); // 父结点索引 while (i > 0 && array[p].getKey().compareTo(array[i].getKey()) < 0) { T temp = array[i]; array[i] = array[p]; array[p] = temp; i = p; p = parent(i); } } /** * 使数组的第i个元素按max heap规则重排 * * @param i * 元素索引 */ private void maxHeapify(int i) { int l = left(i); int r = right(i); int largest; // 当前结点/左子结点/右子结点中最大值的索引 if (l < heapSize && array[l].getKey().compareTo(array[i].getKey()) > 0) { largest = l; } else { largest = i; } if (r < heapSize && array[r].getKey().compareTo(array[largest].getKey()) > 0) { largest = r; } if (largest != i) { // 如果最大值不是当前结点,进行交换 T temp = array[i]; array[i] = array[largest]; array[largest] = temp; // 递归调用,直到当前结点比其子结点大 maxHeapify(largest); } } /** * 计算结点索引为i的元素的父结点的索引 * * @param i * 当前索引 * @return 父结点的索引 */ private int parent(int i) { return (i + 1) / 2 - 1; } /** * 计算结点索引为i的元素的左子结点的索引 * * @param i * 当前索引 * @return 左子结点的索引 */ private int left(int i) { return 2 * i + 1; } /** * 计算结点索引为i的元素的右子结点的索引 * * @param i * 当前索引 * @return 右子结点的索引 */ private int right(int i) { return 2 * i + 2; } } public interface IPriorityQueueElement<KeyType extends Comparable<KeyType>>{ KeyType getKey(); } import junit.framework.TestCase; import junit.framework.TestCase; public class PriorityQueueTest extends TestCase { class Element implements IPriorityQueueElement<Integer> { Integer key; public Element(Integer key) { this.key = key; } public Integer getKey() { return key; } } public void testMaximum() { PriorityQueue<Integer, Element> queue = new PriorityQueue<Integer, Element>(2); queue.insert(new Element(1)); queue.insert(new Element(2)); assertEquals(new Integer(2), queue.maximum().getKey()); queue.insert(new Element(10)); assertEquals(new Integer(10), queue.maximum().getKey()); queue.insert(new Element(3)); assertEquals(new Integer(10), queue.maximum().getKey()); } public void testExtractMax() { PriorityQueue<Integer, Element> queue = new PriorityQueue<Integer, Element>(2); queue.insert(new Element(1)); queue.insert(new Element(2)); assertEquals(new Integer(2), queue.extractMax().getKey()); assertEquals(new Integer(1), queue.maximum().getKey()); } }
算法导论示例-PriorityQueue
最新推荐文章于 2024-06-25 21:37:38 发布