源码分析之PriorityQueue

PriorityQueue优先队列,即维持一个最大(最小)堆,使根节点最大(最小),其儿子节点都不大于(不小于)父节点。

简化的优先队列的变种在排序系列之堆排序和经典算法之最小生成树中使用。

class MiniPriorityQueue {
	private final int queue[];
	private int size;
	public MiniPriorityQueue(int a[]) {
		this.size = a.length;
		this.queue = a;
		heapify();
	}
	private void heapify() {
		for (int i = (this.size >>> 1) - 1; i >= 0; i--)
			siftDown(i, this.queue[i]);
	}
	private void siftDown(int index, int value) {
		int i = this.size >>> 1;
		while (index < i) {
			int j = (index << 1) + 1;
			int temp = this.queue[j];
			int k = j + 1;
			if ((k < this.size) && (this.queue[j] > this.queue[k])) {
				temp = this.queue[(j = k)];
			}
			if (temp > value)
				break;
			this.queue[index] = temp;
			index = j;
		}
		this.queue[index] = value;
	}
	public int pop(){
		int result = this.queue[0];
		int value = this.queue[--this.size];
		siftDown(0, value);
		return this.queue[this.size]=result;
	}
	public boolean isNotEmpty(){
		return this.size != 0;
	}
}

java API中完整版优先队列有兴趣的可以研究一下

 
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.AbstractQueue;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.SortedSet;
 
 public class PriorityQueue<E> extends AbstractQueue<E>
   implements Serializable
 {
   private static final long serialVersionUID = -7720805057305804111L;
   private static final int DEFAULT_INITIAL_CAPACITY = 11;
   private transient Object[] queue;
   private int size = 0;
   private final Comparator<? super E> comparator;
   private transient int modCount = 0;
   private static final int MAX_ARRAY_SIZE = 2147483639;
 
   public PriorityQueue()
   {
     this(11, null);
   }
 
   public PriorityQueue(int paramInt)
   {
     this(paramInt, null);
   }
 
   public PriorityQueue(int paramInt, Comparator<? super E> paramComparator)
   {
     if (paramInt < 1)
       throw new IllegalArgumentException();
     this.queue = new Object[paramInt];
     this.comparator = paramComparator;
   }
 
   public PriorityQueue(Collection<? extends E> paramCollection)
   {
     Object localObject;
     if ((paramCollection instanceof SortedSet)) {
       localObject = (SortedSet)paramCollection;
       this.comparator = ((SortedSet)localObject).comparator();
       initElementsFromCollection((Collection)localObject);
     }
     else if ((paramCollection instanceof PriorityQueue)) {
       localObject = (PriorityQueue)paramCollection;
       this.comparator = ((PriorityQueue)localObject).comparator();
       initFromPriorityQueue((PriorityQueue)localObject);
     }
     else {
       this.comparator = null;
       initFromCollection(paramCollection);
     }
   }
 
   public PriorityQueue(PriorityQueue<? extends E> paramPriorityQueue)
   {
     this.comparator = (Comparator<? super E>) paramPriorityQueue.comparator();
     initFromPriorityQueue(paramPriorityQueue);
   }
 
   public PriorityQueue(SortedSet<? extends E> paramSortedSet)
   {
     this.comparator = (Comparator<? super E>) paramSortedSet.comparator();
     initElementsFromCollection(paramSortedSet);
   }
 
   private void initFromPriorityQueue(PriorityQueue<? extends E> paramPriorityQueue) {
     if (paramPriorityQueue.getClass() == PriorityQueue.class) {
       this.queue = paramPriorityQueue.toArray();
       this.size = paramPriorityQueue.size();
     } else {
       initFromCollection(paramPriorityQueue);
     }
   }
 
   private void initElementsFromCollection(Collection<? extends E> paramCollection) {
     Object[] arrayOfObject = paramCollection.toArray();
     int i = arrayOfObject.length;
     if ((i == 1) || (this.comparator != null))
       for (int j = 0; j < i; j++)
         if (arrayOfObject[j] == null)
           throw new NullPointerException();
     this.queue = arrayOfObject;
     this.size = arrayOfObject.length;
   }
 
   private void initFromCollection(Collection<? extends E> paramCollection)
   {
     initElementsFromCollection(paramCollection);
     heapify();
   }
 
   private void grow(int paramInt)
   {
     int i = this.queue.length;
 
     int j = i + (i < 64 ? i + 2 : i >> 1);
 
     if (j - 2147483639 > 0)
       j = hugeCapacity(paramInt);
     this.queue = Arrays.copyOf(this.queue, j);
   }
 
   private static int hugeCapacity(int paramInt) {
     if (paramInt < 0)
       throw new OutOfMemoryError();
     return paramInt > 2147483639 ? 2147483647 : 2147483639;
   }
 
   public boolean add(E paramE)
   {
     return offer(paramE);
   }
 
   public boolean offer(E paramE)
   {
     if (paramE == null)
       throw new NullPointerException();
     this.modCount += 1;
     int i = this.size;
     if (i >= this.queue.length)
       grow(i + 1);
     this.size = (i + 1);
     if (i == 0)
       this.queue[0] = paramE;
     else
       siftUp(i, paramE);
     return true;
   }
 
   public E peek() {
     if (this.size == 0)
       return null;
     return (E)this.queue[0];
   }
 
   private int indexOf(Object paramObject) {
     if (paramObject != null) {
       for (int i = 0; i < this.size; i++)
         if (paramObject.equals(this.queue[i]))
           return i;
     }
     return -1;
   }
 
   public boolean remove(Object paramObject)
   {
     int i = indexOf(paramObject);
     if (i == -1) {
       return false;
     }
     removeAt(i);
     return true;
   }
 
   boolean removeEq(Object paramObject)
   {
     for (int i = 0; i < this.size; i++) {
       if (paramObject == this.queue[i]) {
         removeAt(i);
         return true;
       }
     }
     return false;
   }
 
   public boolean contains(Object paramObject)
   {
     return indexOf(paramObject) != -1;
   }
 
   public Object[] toArray()
   {
     return Arrays.copyOf(this.queue, this.size);
   }
 
   public <T> T[] toArray(T[] paramArrayOfT)
   {
     if (paramArrayOfT.length < this.size)
     {
       return (T[])Arrays.copyOf(this.queue, this.size, paramArrayOfT.getClass());
     }
     System.arraycopy(this.queue, 0, paramArrayOfT, 0, this.size);
     if (paramArrayOfT.length > this.size)
       paramArrayOfT[this.size] = null;
     return paramArrayOfT;
   }
 
   public Iterator<E> iterator()
   {
     return new Itr();
   }
 
   public int size()
   {
     return this.size;
   }
 
   public void clear()
   {
     this.modCount += 1;
     for (int i = 0; i < this.size; i++)
       this.queue[i] = null;
     this.size = 0;
   }
 
   public E poll() {
     if (this.size == 0)
       return null;
     int i = --this.size;
     this.modCount += 1;
     E localObject1 = (E)this.queue[0];
     E localObject2 = (E)this.queue[i];
     this.queue[i] = null;
     if (i != 0)
       siftDown(0, localObject2);
     return localObject1;
   }
 
   private E removeAt(int paramInt)
   {
     assert ((paramInt >= 0) && (paramInt < this.size));
     this.modCount += 1;
     int i = --this.size;
     if (i == paramInt) {
       this.queue[paramInt] = null;
     } else {
       E localObject = (E)this.queue[i];
       this.queue[i] = null;
       siftDown(paramInt, localObject);
       if (this.queue[paramInt] == localObject) {
         siftUp(paramInt, localObject);
         if (this.queue[paramInt] != localObject)
           return localObject;
       }
     }
     return null;
   }
 
   private void siftUp(int paramInt, E paramE)
   {
     if (this.comparator != null)
       siftUpUsingComparator(paramInt, paramE);
     else
       siftUpComparable(paramInt, paramE);
   }
 
   private void siftUpComparable(int paramInt, E paramE) {
     Comparable localComparable = (Comparable)paramE;
     while (paramInt > 0) {
       int i = paramInt - 1 >>> 1;
       Object localObject = this.queue[i];
       if (localComparable.compareTo(localObject) >= 0)
         break;
       this.queue[paramInt] = localObject;
       paramInt = i;
     }
     this.queue[paramInt] = localComparable;
   }
 
   private void siftUpUsingComparator(int paramInt, E paramE) {
     while (paramInt > 0) {
       int i = paramInt - 1 >>> 1;
       E localObject = (E)this.queue[i];
       if (this.comparator.compare(paramE, localObject) >= 0)
         break;
       this.queue[paramInt] = localObject;
       paramInt = i;
     }
     this.queue[paramInt] = paramE;
   }
 
   private void siftDown(int paramInt, E paramE)
   {
     if (this.comparator != null)
       siftDownUsingComparator(paramInt, paramE);
     else
       siftDownComparable(paramInt, paramE);
   }
 
   private void siftDownComparable(int paramInt, E paramE) {
     Comparable localComparable = (Comparable)paramE;
     int i = this.size >>> 1;
     while (paramInt < i) {
       int j = (paramInt << 1) + 1;
       Object localObject = this.queue[j];
       int k = j + 1;
       if ((k < this.size) && (((Comparable)localObject).compareTo(this.queue[k]) > 0))
       {
         localObject = this.queue[(j = k)];
       }if (localComparable.compareTo(localObject) <= 0)
         break;
       this.queue[paramInt] = localObject;
       paramInt = j;
     }
     this.queue[paramInt] = localComparable;
   }
 
   private void siftDownUsingComparator(int paramInt, E paramE) {
     int i = this.size >>> 1;
     while (paramInt < i) {
       int j = (paramInt << 1) + 1;
       E localObject = (E)this.queue[j];
       int k = j + 1;
       if ((k < this.size) && (this.comparator.compare(localObject, (E)this.queue[k]) > 0))
       {
         localObject = (E)this.queue[(j = k)];
       }if (this.comparator.compare(paramE, localObject) <= 0)
         break;
       this.queue[paramInt] = localObject;
       paramInt = j;
     }
     this.queue[paramInt] = paramE;
   }
 
   private void heapify()
   {
     for (int i = (this.size >>> 1) - 1; i >= 0; i--)
       siftDown(i, (E)this.queue[i]);
   }
 
   public Comparator<? super E> comparator()
   {
     return this.comparator;
   }
 
   private void writeObject(ObjectOutputStream paramObjectOutputStream)
     throws IOException
   {
     paramObjectOutputStream.defaultWriteObject();
 
     paramObjectOutputStream.writeInt(Math.max(2, this.size + 1));
 
     for (int i = 0; i < this.size; i++)
       paramObjectOutputStream.writeObject(this.queue[i]);
   }
 
   private void readObject(ObjectInputStream paramObjectInputStream)
     throws IOException, ClassNotFoundException
   {
     paramObjectInputStream.defaultReadObject();
 
     paramObjectInputStream.readInt();
 
     this.queue = new Object[this.size];
 
     for (int i = 0; i < this.size; i++) {
       this.queue[i] = paramObjectInputStream.readObject();
     }
 
     heapify();
   }
 
   private final class Itr
     implements Iterator<E>
   {
     private int cursor = 0;
 
     private int lastRet = -1;
 
     private ArrayDeque<E> forgetMeNot = null;
 
     private E lastRetElt = null;
 
     private int expectedModCount = PriorityQueue.this.modCount;
 
     private Itr() {  }
 
     public boolean hasNext() { return (this.cursor < PriorityQueue.this.size) || ((this.forgetMeNot != null) && (!this.forgetMeNot.isEmpty()));
     }
 
     public E next()
     {
       if (this.expectedModCount != PriorityQueue.this.modCount)
         throw new ConcurrentModificationException();
       if (this.cursor < PriorityQueue.this.size)
         return (E)PriorityQueue.this.queue[(this.lastRet = this.cursor++)];
       if (this.forgetMeNot != null) {
         this.lastRet = -1;
         this.lastRetElt = this.forgetMeNot.poll();
         if (this.lastRetElt != null)
           return this.lastRetElt;
       }
       throw new NoSuchElementException();
     }
 
     public void remove() {
       if (this.expectedModCount != PriorityQueue.this.modCount)
         throw new ConcurrentModificationException();
       if (this.lastRet != -1) {
         E localObject = (E)PriorityQueue.this.removeAt(this.lastRet);
         this.lastRet = -1;
         if (localObject == null) {
           this.cursor -= 1;
         } else {
           if (this.forgetMeNot == null)
             this.forgetMeNot = new ArrayDeque();
           this.forgetMeNot.add(localObject);
         }
       } else if (this.lastRetElt != null) {
         PriorityQueue.this.removeEq(this.lastRetElt);
         this.lastRetElt = null;
       } else {
         throw new IllegalStateException();
       }
       this.expectedModCount = PriorityQueue.this.modCount;
     }
   }
   public static void main(String[] args) {
	   PriorityQueue<Integer> queue = new PriorityQueue<>();
	   for(int i=0;i<10;i++){
		   int result = (int)(Math.random()*100); 
		   System.out.println(queue + " "+ result);
		   queue.add(result);
		   System.out.println(queue);
	   }
	   for(int i=0;i<10;i++){
		   System.out.println(queue.poll());
		   System.out.println(queue);
	   }
   }
 }



 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值