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 }
时间: 2024-10-23 22:43:38