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 }