-
Notifications
You must be signed in to change notification settings - Fork 85
/
MinHeap.java
152 lines (136 loc) · 2.69 KB
/
MinHeap.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/**
* 最小堆
* 完全二叉树实现、树中的根结点都表示树中的最小元素结点
*
* @author ronglexie
* @version 2018/8/25
*/
public class MinHeap<E extends Comparable<E>> {
private Array<E> data;
public MinHeap(int capacity){
data = new Array<>(capacity);
}
public MinHeap() {
data = new Array<>();
}
public int size(){
return data.getSize();
}
public boolean isEmpty(){
return data.isEmpty();
}
/**
* 查找用数组实现的完全二叉树中该索引下节点的父亲节点的索引
*
* @param index
* @return int
* @author ronglexie
* @version 2018/8/19
*/
public int parent(int index){
if(index == 0){
throw new IllegalArgumentException("root doesn't have parent.");
}
return (index - 1) / 2;
}
/**
* 查找用数组实现的完全二叉树中该索引下节点的左孩子节点的索引
*
* @param index
* @return int
* @author ronglexie
* @version 2018/8/19
*/
public int leftChild(int index){
return (index * 2) + 1;
}
/**
* 查找用数组实现的完全二叉树中该索引下节点的右孩子节点的索引
*
* @param index
* @return int
* @author ronglexie
* @version 2018/8/19
*/
public int rightChild(int index){
return (index * 2) + 2;
}
/**
* 向最大堆中添加元素
*
* @param e
* @return void
* @author ronglexie
* @version 2018/8/19
*/
public void add(E e){
data.addLast(e);
shifUp(data.getSize() - 1);
}
/**
* 上浮节点
*
* @param k
* @return void
* @author ronglexie
* @version 2018/8/19
*/
private void shifUp(int k) {
while (k > 0 && data.get(parent(k)).compareTo(data.get(k)) > 0){
data.swap(k,parent(k));
k = parent(k);
}
}
/**
* 查找堆中最小值
*
* @param
* @return E
* @author ronglexie
* @version 2018/8/19
*/
public E findMin(){
if(data .getSize() == 0){
throw new IllegalArgumentException("FindMax failed. heap is empty.");
}
return data.get(0);
}
/**
* 取出最小值
*
* @param
* @return E
* @author ronglexie
* @version 2018/8/20
*/
public E extractMin(){
E result = findMin();
data.swap(0,data.getSize() - 1);
data.removeLast();
siftDown(0);
return result;
}
/**
* 下沉节点
*
* @param k
* @return void
* @author ronglexie
* @version 2018/8/25
*/
private void siftDown(int k) {
while (k >= 0 && leftChild(k) < data.getSize()){
int j = leftChild(k);
//找到k节点的左右子节点的最大值j
if (j + 1 < data.getSize() && data.get(j + 1).compareTo(data.get(j)) < 0) {
j = rightChild(k);
}
//比较大小判断是否还需要下沉操作
if(data.get(k).compareTo(data.get(j)) < 0){
break;
}
data.swap(k,j);
k = j;
}
}
}