优先级队列-堆实现

  1 package sorts;

  2 

  3 import java.util.ArrayList;

  4 import java.util.List;

  5 import java.util.Random;

  6 

  7 public class PriorityQueue<T extends Comparable<T>> { // min-heap

  8     private List<T> heap = new ArrayList<>();

  9     private static final int ROOT_INDEX = 0;

 10     private static final int PRE_ROOT_INDEX = ROOT_INDEX - 1;

 11     public void offer(T obj) {

 12         heap.add(obj);//在最后增加一个元素

 13         int index = heap.size() - 1;//最后一个元素的索引

 14         while (index > ROOT_INDEX) {//在堆中加一个元素后,调整堆使其再成为一个堆

 15             index = stepUpHeap(index);//上浮

 16         }

 17     }

 18     private int stepUpHeap(int index) {

 19         int parentIndex = parent(index);//获取父节点的索引

 20         T element = heap.get(index);

 21         T parent  = heap.get(parentIndex);

 22         if (parent.compareTo(element) > 0) { //父节点大于儿子节点,交换

 23               heap.set(parentIndex, element);

 24               heap.set(index, parent);

 25               return parentIndex;  // 跳到父索引

 26          } else   

 27               return ROOT_INDEX; //不需要交换

 28     }

 29     public T poll() {

 30         if (isEmpty())

 31             throw new RuntimeException();

 32         int index = heap.size() - 1;//最后一个元素的索引

 33         T least;

 34         if(index==0){

 35            least = heap.get(index);

 36            heap.remove(index);

 37         }

 38         else{

 39             T element = heap.get(index);//取最后一个元素

 40             least  = heap.get(ROOT_INDEX);//取堆的根元素

 41             heap.set(ROOT_INDEX, element);//交换这两个元素

 42             heap.set(index, least);

 43             heap.remove(index);//删除最后一个元素

 44             stepDownHeap(ROOT_INDEX);//下沉调整,使之再次成为堆

 45          }

 46          return least;

 47     }

 48     private void stepDownHeap(int index) {

 49         int p = index;//parent

 50         int lchild = lchild(p);//左子节点

 51         T temp = heap.get(p);

 52         while(lchild<heap.size()){

 53         if(lchild+1<heap.size() && heap.get(lchild+1).compareTo(heap.get(lchild))<0)//右节点比左节点小

 54             lchild = lchild + 1;//取两个儿子节点中小的一个

 55             if(temp.compareTo(heap.get(lchild))<=0)//不需要调整了

 56                     break;

 57             else {

 58                  heap.set(p,heap.get(lchild));//较小的儿子节点上浮

 59                  p = lchild;

 60                  lchild = lchild(p);//继续调整

 61             }

 62         }

 63         heap.set(p,temp);//最后要将temp放到p

 64     }

 65     public T peek() {

 66         if (isEmpty())

 67             throw new RuntimeException();

 68         return heap.get(0);

 69     }

 70     public boolean isEmpty() {

 71         return heap.isEmpty();

 72     }

 73     public int size() {

 74         return heap.size();

 75     }

 76     @Override

 77     public String toString() {

 78         return heap.toString();

 79     }

 80     // index starts from 0

 81     private int parent(int index) {

 82         if (index%2==0) {

 83             return ( index / 2 ) - 1;

 84         } else {

 85             return index / 2;

 86         }

 87     }

 88     private int lchild(int index) {

 89         return index * 2 + 1;

 90     }

 91     private int rchild(int index) {

 92         return index * 2 + 2;

 93     }

 94     // test

 95     public static void main(String[] args) {

 96         Random random = new Random();

 97         PriorityQueue<Integer> pq = new PriorityQueue<>();

 98         for (int i = 0; i < 10; i++) {

 99             pq.offer(random.nextInt(100));

100         }

101         for (int i = 0; i < 10; i++) {

102             System.out.print(pq.poll() + " ");

103         }

104     }

105 }

 

你可能感兴趣的:(优先级)