package kitsion.util;
/**
* PriorityQueue class implemented via the binary heap.
*/
public class PriorityQueue<AnyType> extends AbstractCollection<AnyType>
implements Queue<AnyType> {
public PriorityQueue() {
currentSize = 0;
cmp = null;
array = (AnyType[]) new Object[DEFAULT_CAPACITY + 1];
}
/**
* Construct an empty PriorityQueue with a specified comparator
*
* @param c
*/
public PriorityQueue(Comparator<? super AnyType> c) {
currentSize = 0;
cmp = c;
array = (AnyType[]) new Object[DEFAULT_CAPACITY + 1];
}
/**
* Construct a PriorityQueue from another Collection
*
* @param coll
*/
public PriorityQueue(Collection<? extends AnyType> coll) {
cmp = null;
currentSize = coll.size();
array = (AnyType[]) new Object[(currentSize + 2) * 11 / 10];
int i = 1;
for (AnyType item : coll)
array[i++] = item;
buildHeap();
}
/**
* Returns the number of items in this PriorityQueue
*/
public int size() {
return currentSize;
}
public void clear() {
currentSize = 0;
}
/**
* Returns an iterator over the elements in this PriorityQueue
*/
public Iterator<AnyType> iterator() {
return new Iterator<AnyType>() {
int current = 0;
public boolean hasNext() {
return current != size();
}
public AnyType next() {
if (hasNext())
return array[++current];
else
throw new NoSuchElementException();
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
/**
* Returns the smallest item in the priority queue
*/
public AnyType element() {
if (isEmpty())
throw new NoSuchElementException();
return array[1];
}
/**
* Adds an item to this PriorityQueue.
*/
public boolean add(AnyType x) {
if (currentSize + 1 == array.length)
doubleArray();
/* 详细注解: 增加堆的当前大小,并设置空结点为新增加的结点 */
int hole = ++currentSize;
/* 详细注解: 把x作为负无穷标志,放入位置0 */
array[0] = x;
/* 详细注解: 只要父结点中的项大于x,重复执行向上过滤的策略,指将父结点中的项下移到空结点中,然后将空结点上移到父结点 */
for (; compare(x, array[hole / 2]) < 0; hole /= 2)
array[hole] = array[hole / 2];
array[hole] = x;
return true;
}
/**
* Removes the smallest item in the priority queue.
*/
public AnyType remove() {
AnyType minItem = element();
array[1] = array[currentSize--];
percolateDown(1);
return minItem;
}
/**
* 详细注解: percolateDown的一个参数指示空结点的位置,然后空结点中项被移出,开台向下过滤,
* 当没有左孩子,循环结束,因为偶数大小的堆里的最后一个结点是仅有一个子结点,所以还要在向下过滤 中,进行测试.
*
* @param hole
*/
public void percolateDown(int hole) {
int child;
AnyType tmp = array[hole];
for (; hole * 2 <= currentSize; hole = child) {
child = 2 * hole;
if (child != currentSize
&& compare(array[child + 1], array[child]) < 0)
child++;
if (compare(array[child], tmp) < 0)
array[hole] = array[child];
else
break;
}
array[hole] = tmp;
}
/**
* 逆序采用向下过滤策略,构造有序堆
*/
public void buildHeap() {
for (int i = currentSize / 2; i > 0; i--)
percolateDown(i);
}
// number of elements in heap
private int currentSize;
// The heap array
private AnyType[] array;
private Comparator<? super AnyType> cmp;
private static final int DEFAULT_CAPACITY = 100;
/**
* Internal method to extend array
*/
private void doubleArray() {
AnyType[] newArray;
newArray = (AnyType[]) new Object[array.length * 2];
for (int i = 0; i < array.length; i++)
newArray[i] = array[i];
array = newArray;
}
/**
* Compares lhs and rhs using comparator if provided by cmp, or the default
* comarator
*
* @param lhs
* @param rhs
* @return
*/
private int compare(AnyType lhs, AnyType rhs) {
if (cmp == null)
return ((Comparable) lhs).compareTo(rhs);
else
return cmp.compare(lhs, rhs);
}
}
/**
* PriorityQueue class implemented via the binary heap.
*/
public class PriorityQueue<AnyType> extends AbstractCollection<AnyType>
implements Queue<AnyType> {
public PriorityQueue() {
currentSize = 0;
cmp = null;
array = (AnyType[]) new Object[DEFAULT_CAPACITY + 1];
}
/**
* Construct an empty PriorityQueue with a specified comparator
*
* @param c
*/
public PriorityQueue(Comparator<? super AnyType> c) {
currentSize = 0;
cmp = c;
array = (AnyType[]) new Object[DEFAULT_CAPACITY + 1];
}
/**
* Construct a PriorityQueue from another Collection
*
* @param coll
*/
public PriorityQueue(Collection<? extends AnyType> coll) {
cmp = null;
currentSize = coll.size();
array = (AnyType[]) new Object[(currentSize + 2) * 11 / 10];
int i = 1;
for (AnyType item : coll)
array[i++] = item;
buildHeap();
}
/**
* Returns the number of items in this PriorityQueue
*/
public int size() {
return currentSize;
}
public void clear() {
currentSize = 0;
}
/**
* Returns an iterator over the elements in this PriorityQueue
*/
public Iterator<AnyType> iterator() {
return new Iterator<AnyType>() {
int current = 0;
public boolean hasNext() {
return current != size();
}
public AnyType next() {
if (hasNext())
return array[++current];
else
throw new NoSuchElementException();
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
/**
* Returns the smallest item in the priority queue
*/
public AnyType element() {
if (isEmpty())
throw new NoSuchElementException();
return array[1];
}
/**
* Adds an item to this PriorityQueue.
*/
public boolean add(AnyType x) {
if (currentSize + 1 == array.length)
doubleArray();
/* 详细注解: 增加堆的当前大小,并设置空结点为新增加的结点 */
int hole = ++currentSize;
/* 详细注解: 把x作为负无穷标志,放入位置0 */
array[0] = x;
/* 详细注解: 只要父结点中的项大于x,重复执行向上过滤的策略,指将父结点中的项下移到空结点中,然后将空结点上移到父结点 */
for (; compare(x, array[hole / 2]) < 0; hole /= 2)
array[hole] = array[hole / 2];
array[hole] = x;
return true;
}
/**
* Removes the smallest item in the priority queue.
*/
public AnyType remove() {
AnyType minItem = element();
array[1] = array[currentSize--];
percolateDown(1);
return minItem;
}
/**
* 详细注解: percolateDown的一个参数指示空结点的位置,然后空结点中项被移出,开台向下过滤,
* 当没有左孩子,循环结束,因为偶数大小的堆里的最后一个结点是仅有一个子结点,所以还要在向下过滤 中,进行测试.
*
* @param hole
*/
public void percolateDown(int hole) {
int child;
AnyType tmp = array[hole];
for (; hole * 2 <= currentSize; hole = child) {
child = 2 * hole;
if (child != currentSize
&& compare(array[child + 1], array[child]) < 0)
child++;
if (compare(array[child], tmp) < 0)
array[hole] = array[child];
else
break;
}
array[hole] = tmp;
}
/**
* 逆序采用向下过滤策略,构造有序堆
*/
public void buildHeap() {
for (int i = currentSize / 2; i > 0; i--)
percolateDown(i);
}
// number of elements in heap
private int currentSize;
// The heap array
private AnyType[] array;
private Comparator<? super AnyType> cmp;
private static final int DEFAULT_CAPACITY = 100;
/**
* Internal method to extend array
*/
private void doubleArray() {
AnyType[] newArray;
newArray = (AnyType[]) new Object[array.length * 2];
for (int i = 0; i < array.length; i++)
newArray[i] = array[i];
array = newArray;
}
/**
* Compares lhs and rhs using comparator if provided by cmp, or the default
* comarator
*
* @param lhs
* @param rhs
* @return
*/
private int compare(AnyType lhs, AnyType rhs) {
if (cmp == null)
return ((Comparable) lhs).compareTo(rhs);
else
return cmp.compare(lhs, rhs);
}
}