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
最新推荐文章于 2025-06-18 20:09:51 发布
本文介绍了一个基于最大堆实现的优先队列数据结构。该优先队列支持插入元素、获取及移除最大值等操作,并提供了完整的Java代码实现及单元测试案例。
882

被折叠的 条评论
为什么被折叠?



