首页 > 代码库 > 优先级队列-堆实现

优先级队列-堆实现

  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 }

 

优先级队列-堆实现