package org.loda.structure;
/**
*
* @ClassName: MinQ
* @Description: 从小到大排列的优先队列
* @author minjun
* @date 2015年5月20日 上午10:01:29
*
*/
@SuppressWarnings("unchecked")
public class MinQ<Item extends Comparable<Item>> {
// 利用数组存储队列元素
private Item[] items;
// 队列元素数量
private int heapSize;
// 初始化队列大小
private int size = 0;
public MinQ() {
this(10);
}
public MinQ(int size) {
this.size = size;
items = (Item[]) new Comparable[size];
}
// 添加元素
public void offer(Item item) {
if (heapSize == size)
resize();
items[heapSize++] = item;
shiftUp(heapSize - 1);
}
//两倍扩容数组
private void resize() {
this.size=this.size<<1;
Item[] newItems=(Item[]) new Comparable[size];
for(int i=0;i<items.length;i++){
newItems[i]=items[i];
}
items=newItems;
}
// 获取优先级最高的元素
public Item poll() {
if (isEmpty())
throw new RuntimeException("没有元素了");
Item item = items[0];
items[0] = null;
exchange(0, --heapSize);
shiftDown(0);
return item;
}
// 判断队列是否为空
public boolean isEmpty() {
return heapSize == 0;
}
//获取队列中元素的个数
public int size(){
return heapSize;
}
//打印优先队列中的堆结构
public void print() {
System.out.println("===================");
for (int i = 0; i < heapSize && left(i) < heapSize
&& right(i) < heapSize; i++) {
System.out.print(items[i] + "\t左:" + items[left(i)] + ",右:"
+ items[right(i)] + "\t");
System.out.println();
}
System.out.println("===================");
}
// 上移
private void shiftUp(int i) {
int parent = parent(i);
if (i > 0 && less(items[i], items[parent])) {
exchange(i, parent);
shiftUp(parent);
}
}
// 下沉
private void shiftDown(int i) {
int left = left(i);
int right = right(i);
int least = i;
if (left < heapSize && less(items[left], items[i])) {
least = left;
}
if (right < heapSize && less(items[right], items[least])) {
least = right;
}
if (least != i) {
exchange(least, i);
shiftDown(least);
}
}
// a是否小于b
private boolean less(Item a, Item b) {
return a.compareTo(b) < 0;
}
// 右孩子节点
private int right(int i) {
return i * 2 + 2;
}
// 左孩子节点
private int left(int i) {
return i * 2 + 1;
}
// 父节点
private int parent(int i) {
return (i - 1) / 2;
}
private void exchange(int i, int j) {
Item t = items[i];
items[i] = items[j];
items[j] = t;
}
public static void main(String[] args) {
// MinQ<Integer> q = new MinQ<Integer>();
//
// for (int i = 0; i < 10; i++) {
// q.offer(Math.round((float) Math.random() * 100));
// }
MinQ<String> q = new MinQ<String>();
q.offer("jack");
q.offer("shelock");
q.offer("allen");
q.offer("andy");
q.offer("jetty");
q.print();
while (!q.isEmpty()) {
System.out.println(q.poll());
}
}
}