- [1 æ¯è¾å¨ä¸å ](#1)
* [1.1 å ç»æ](#11)
+ [1.1.1 å®å
¨äºåæ ç»æ](#111)
+ [1.1.2 æ°ç»å®ç°å ](#112)
+ [1.1.3 å¤§æ ¹å ä¸å°æ ¹å ](#113)
+ [1.1.4 æå»ºå ](#114)
+ [1.1.5 å æåº](#115)
+ [1.1.6 è¯è¨ãç³»ç»æä¾çå åæåå çéæ©](#116)
- [1.1.6.1 ç³»ç»å®ç°çå ](#1161)
- [1.1.6.2 ç³»ç»å åæåå éæ©](#1162)
* [1.2 æ¯è¾å¨](#12)
1 æ¯è¾å¨ä¸å
>
1.1 å ç»æ
>
1.1.1 å®å
¨äºåæ ç»æ
>
> å®å
¨äºåæ ç»æï¼è¦ä¹æ¬å±æ¯æ»¡çï¼è¦ä¹å
满左边çï¼ä»¥ä¸é½æ¯å®å
¨äºåæ
1.
```
graph TD
A-->B
A-->C
```
2.
```
graph TD
A-->B
A-->C
B-->D
B-->E
C-->F
```
1.1.2 æ°ç»å®ç°å
>
- å ç»æå°±æ¯ç¨æ°ç»å®ç°çå®å
¨äºåæ ç»æ
> ç¨æ°ç»å®ç°å®å
¨äºåæ ç»æï¼ä»æ°ç»ä¸æ 0å¼å§ï¼å½æä¾æ¬¡è¡¥é½äºåæ ç»æçæ°æ®
```
graph TD
0--> 1
0--> 2
1--> 3
1-->4
2-->5
2-->6
```
æä½ç½®içå·¦å©å䏿 为ï¼
```math
lchild = 2*i + 1
```
æä½ç½®içå³å©åç䏿 为ï¼
```math
rchild = 2*i + 2
```
æä½ç½®içç¶èç¹ä½ç½®ä¸ºï¼
```math
parent = (i-1) / 2
```
> 彿们ä¸ä½¿ç¨æ°ç»ç0䏿 ï¼ä»1ä½ç½®å¼å§æå»ºå®å
¨äºåæ æ¶ï¼æ¹ä¾¿ä½¿ç¨ä½æä½ï¼
æä½ç½®içå·¦å©å䏿 为ï¼
```math
lchild = 2*i <==> i << 1
```
æä½ç½®içå³å©åç䏿 为ï¼
```math
rchild = 2*i + 1 <==> (i << 1) | 1
```
æä½ç½®içç¶èç¹ä½ç½®ä¸ºï¼
```math
parent = i / 2 <==> i >> 1
```
1.1.3 å¤§æ ¹å ä¸å°æ ¹å
>
- å®å
¨äºåæ ä¸å¦ææ¯æ£µåæ çæå¤§å¼é½å¨é¡¶é¨å°±æ¯å¤§æ ¹å
- å®å
¨äºåæ ä¸å¦ææ¯é¢åæ çæå°å¼é½å¨é¡¶é¨å°±æ¯å°æ ¹å
==æä»¬è®¤ä¸ºå å°±æ¯å¤§æ ¹å æè
å°æ ¹å ï¼æ¢ä¸æ¯å¤§æ ¹å ä¹ä¸æ¯å°æ ¹å çå®å
¨äºåæ åªæ¯å®å
¨äºåæ ï¼ä¸è½ç§°ä¹ä¸ºå ==
1.1.4 æå»ºå
- å ç»æçheapInsertä¸heapifyæä½
heapInsert
æè·¯ï¼ä¾å¦æä»¬è¦æå»ºä¸ä¸ªå¤§æ ¹å ï¼æä»¬æææçæ°ä¾æ¬¡æ·»å å°ä¸ä¸ªæ°ç»ï¼ä¸æ ä»0å¼å§ï¼ä¸å»ï¼æ¯æ¬¡æ·»å ä¸ä¸ªæ°çæ¶åï¼è¦å»ç¨æ¾ç¶äº²èç¹çå
¬å¼parent = (i-1) / 2æ¾å°ç¶èç¹åºæ¯è¾ï¼å¦ææ¯ç¶èç¹å¤§å°±åç¶èç¹äº¤æ¢åä¸ç§»å¨ï¼ç§»å¨ååç¨èªå·±å½åä½ç½®åç¶äº²èç¹æ¯è¾...ï¼å°äºçäºç¶èç¹ä¸åå¤çãè¿æ ·ç¨æ·æ¯å ä¸ä¸ªæ°ï¼æä»¬é½è½ä¿è¯è¯¥ç»ææ¯å¤§æ ¹å ï¼å¯¹åºä»£ç çpushæ¹æ³
> æä»¬çè°æ´ä»£ä»·å®é
ä¸å°±æ¯è¿é¢æ çé«åº¦å±æ°ï¼logN
heapify
> åå ç»æï¼å 餿大å¼ï¼ç»§ç»è°æ´ç»´ææå¤§æ ¹å
æè·¯ï¼æä»¬å é¤äºæå¤§å¼ï¼ä¹å°±æ¯arr[0]ä½ç½®ï¼ä¹åæä»¬æå ææ«å°¾çä½ç½®è°æ´å°arr[0]ä½ç½®ï¼å 大å°åä¸ã让ç°å¨arr[0]ä½ç½®çæ°æ¾å·¦å³å©åæ¯è¾...ï¼è¿è¡hearifyæä½ï¼è®©å
¶æ²ä¸å»ãæ²å°åéçä½ç½®ä¹åï¼ä»ç¶æ¯å¤§æ ¹å ã对åºä»£ç çpopæ¹æ³
> heapifyç䏿²æä½ï¼ä»ç¶æ¯æ çé«åº¦ï¼logN
> å ç»æå¾éè¦å¾éè¦
```Java
package class04;
public class Code02_Heap01 {
public static class MyMaxHeap {
// æä»¬çå¤§æ ¹å
private int[] heap;
private final int limit;
// 表示ç®åè¿ä¸ªå æ¶éäºå¤å°ä¸ªæ°ï¼ä¹è¡¨ç¤ºæ·»å çä¸ä¸ä¸ªæ°åºè¯¥æ¾å¨åªä¸ªä½ç½®
private int heapSize;
public MyMaxHeap(int limit) {
heap = new int[limit];
this.limit = limit;
heapSize = 0;
}
public boolean isEmpty() {
return heapSize == 0;
}
public boolean isFull() {
return heapSize == limit;
}
// æ¯å å
¥ä¸ä¸ªæ°ï¼éè¦å¨æç»´æå ç»æ
public void push(int value) {
if (heapSize == limit) {
throw new RuntimeException("heap is full");
}
heap[heapSize] = value;
// value heapSize
heapInsert(heap, heapSize++);
}
// ç¨æ·æ¤æ¶ï¼è®©ä½ è¿åæå¤§å¼ï¼å¹¶ä¸å¨å¤§æ ¹å ä¸ï¼ææå¤§å¼å æ
// å©ä¸çæ°ï¼ä¾ç¶ä¿æå¤§æ ¹å ç»ç»
public int pop() {
int ans = heap[0];
swap(heap, 0, --heapSize);
heapify(heap, 0, heapSize);
return ans;
}
// å¾å 䏿·»å æ°ï¼éè¦ç¨å½åä½ç½®æ¾ç¶èç¹æ¯è¾
private void heapInsert(int[] arr, int index) {
// arr[index]
// arr[index] 䏿¯ arr[indexç¶]å¤§äº ï¼ å
// index = 0æ¶ä¹å
while (arr[index] > arr[(index - 1) / 2]) {
swap(arr, index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
// ä»indexä½ç½®ï¼å¾ä¸çï¼ä¸æç䏿²ï¼
// åçæ¡ä»¶ï¼æçå©åé½ä¸åæ¯æå¤§ï¼å·²ç»æ²¡å©åäº
private void heapify(int[] arr, int index, int heapSize) {
int left = index * 2 + 1;
// å·¦å©å没è¶çï¼å¦æå·¦å©åè¶çæå©åä¸å®ä¹è¶ç
while (left < heapSize) {
// å·¦å³ä¸¤ä¸ªå©åä¸ï¼è°å¤§ï¼è°æèªå·±ç䏿 ç»largest
// ä»ä¹è¯·æ¬¾ä¸éæ©å³ -> (1) æå³å©å && (2)å³å©åç弿¯å·¦å©å大æè¡
// å¦åï¼å·¦
int largest = left + 1 < heapSize && arr[left + 1] > arr[left] ? left + 1 : left;
// å·¦å³å©å䏿大å¼ï¼åå½å弿¯è¾ï¼è°å¤§è°æä¸æ ç»largest(å½åï¼å·¦ï¼å³çæå¤§å¼ä¸æ )
largest = arr[largest] > arr[index] ? largest : index;
// indexä½ç½®ä¸çæ°æ¯å·¦å³å©åçæ°é½å¤§ï¼å·²ç»æ é䏿²
if (largest == index) {
break;
}
// 交æ¢åï¼ç»§ç»æ¾å·¦å³å©åè¿è¡æ¯è¾ï¼å¨èå¤å§
swap(arr, largest, index);
index = largest;
left = index * 2 + 1;
}
}
private void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
// æ´åï¼O(N)å¤æåº¦å®ç°çå¤§æ ¹å ãç¨æ¥å对æ°å¨
public static class RightMaxHeap {
private int[] arr;
private final int limit;
private int size;
public RightMaxHeap(int limit) {
arr = new int[limit];
this.limit = limit;
size = 0;
}
public boolean isEmpty() {
return size == 0;
}
public boolean isFull() {
return size == limit;
}
public void push(int value) {
if (size == limit) {
throw new RuntimeException("heap is full");
}
arr[size++] = value;
}
public int pop() {
int maxIndex = 0;
for (int i = 1; i < size; i++) {
if (arr[i] > arr[maxIndex]) {
maxIndex = i;
}
}
int ans = arr[maxIndex];
arr[maxIndex] = arr[--size];
return ans;
}
}
public static void main(String[] args) {
int value = 1000;
int limit = 100;
int testTimes = 1000000;
for (int i = 0; i < testTimes; i++) {
int curLimit = (int) (Math.random() * limit) + 1;
MyMaxHeap my = new MyMaxHeap(curLimit);
RightMaxHeap test = new RightMaxHeap(curLimit);
int curOpTimes = (int) (Math.random() * limit);
for (int j = 0; j < curOpTimes; j++) {
if (my.isEmpty() != test.isEmpty()) {
System.out.println("Oops!");
}
if (my.isFull() != test.isFull()) {
System.out.println("Oops!");
}
if (my.isEmpty()) {
int curValue = (int) (Math.random() * value);
my.push(curValue);
test.push(curValue);
} else if (my.isFull()) {
if (my.pop() != test.pop()) {
System.out.println("Oops!");
}
} else {
if (Math.random() < 0.5) {
int curValue = (int) (Math.random() * value);
my.push(curValue);
test.push(curValue);
} else {
if (my.pop() != test.pop()) {
System.out.println("Oops!");
}
}
}
}
}
System.out.println("finish!");
}
}
```
1.1.5 å æåº
>
1. 对äºç¨æ·ç»çæææ°æ®ï¼æä»¬å
让å
¶æå»ºæä¸ºå¤§æ ¹å
2. 对äº0å°N-1ä½ç½®çæ°ï¼æä»¬ä¾æ¬¡è®©N-1ä½ç½®çæ°å0ä½ç½®çæ°ï¼å
¨å±æå¤§å¼ï¼äº¤æ¢,æ¤æ¶å
¨å±æå¤§å¼æ¥å°äºæ°ç»æå¤§ä½ç½®ï¼å 大å°åä¸ï¼åheapifyè°æ´æå¤§æ ¹å ãåç¨N-2ä½ç½®çæ°åè°æ´åç0ä½ç½®çæ°äº¤æ¢ï¼ç¸åæä½ãç´è³0ä½ç½®å0ä½ç½®äº¤æ¢ãæ¯æ¬¡heapify为logNï¼äº¤æ¢è°æ´äºN次
3. æä»¥å æåºçæ¶é´å¤æåº¦ä¸ºO(NlogN)
4. å æåºé¢ä¸ºç©ºé´å¤æåº¦ä¸ºO(1)ï¼ä¸ä¸åå¨éå½è¡ä¸º
```Java
package class04;
import java.util.Arrays;
import java.util.PriorityQueue;
public class Code04_HeapSort {
// å æåºé¢å¤ç©ºé´å¤æåº¦O(1)
public static void heapSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
// O(N*logN),åå§çæ¬
// for (int i = 0; i < arr.length; i++) { // O(N)
// heapInsert(arr, i); // O(logN)
// }
// ä¼åçæ¬ï¼heapInsertæ¹ä¸ºheapifyã仿«å°¾å¼å§çæ¯å¦éè¦heapify=ãO(N)å¤æåº¦ã
// 使¯è¿åªæ¯ä¼åäºåæé½æ¯æå»ºå ï¼O(NlogN)ï¼ï¼æç»çå æåºä»ç¶æ¯O(NlogN)
for (int i = arr.length - 1; i >= 0; i--) {
heapify(arr, i, arr.length);
}
int heapSize = arr.length;
swap(arr, 0, --heapSize);
// O(N*logN)
while (heapSize > 0) { // O(N)
heapify(arr, 0, heapSize); // O(logN)
swap(arr, 0, --heapSize); // O(1)
}
}
// arr[index]åæ¥çæ°ï¼å¾ä¸
public static void heapInsert(int[] arr, int index) {
while (arr[index] > arr[(index - 1) / 2]) {
swap(arr, index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
// arr[index]ä½ç½®çæ°ï¼è½å¦å¾ä¸ç§»å¨
public static void heapify(int[] arr, int index, int heapSize) {
// å·¦å©åç䏿
int left = index * 2 + 1;
// 䏿¹è¿æå©åçæ¶å
while (left < heapSize) {
// 两个å©åä¸ï¼è°çå¼å¤§ï¼æä¸æ ç»largest
// 1ï¼åªæå·¦å©åï¼left -> largest
// 2) åæ¶æå·¦å©ååå³å©åï¼å³å©åçå¼<= å·¦å©åçå¼ï¼left -> largest
// 3) åæ¶æå·¦å©ååå³å©åå¹¶ä¸å³å©åçå¼> å·¦å©åçå¼ï¼ right -> largest
int largest = left + 1 < heapSize && arr[left + 1] > arr[left] ? left + 1 : left;
// ç¶åè¾å¤§çå©åä¹é´ï¼è°çå¼å¤§ï¼æä¸æ ç»largest
largest = arr[largest] > arr[index] ? largest : index;
if (largest == index) {
break;
}
swap(arr, largest, index);
index = largest;
left = index * 2 + 1;
}
}
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// for test
public static void comparator(int[] arr) {
Arrays.sort(arr);
}
// for test
public static int[] generateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
}
return arr;
}
// for test
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// for test
public static boolean isEqual(int[] arr1, int[] arr2) {
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
return false;
}
if (arr1 == null && arr2 == null) {
return true;
}
if (arr1.length != arr2.length) {
return false;
}
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
}
// for test
public static void printArray(int[] arr) {
if (arr == null) {
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
// for test
public static void main(String[] args) {
// é»è®¤å°æ ¹å
PriorityQueue heap = new PriorityQueue<>();
heap.add(6);
heap.add(8);
heap.add(0);
heap.add(2);
heap.add(9);
heap.add(1);
while (!heap.isEmpty()) {
System.out.println(heap.poll());
}
int testTime = 500000;
int maxSize = 100;
int maxValue = 100;
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue);
int[] arr2 = copyArray(arr1);
heapSort(arr1);
comparator(arr2);
if (!isEqual(arr1, arr2)) {
succeed = false;
break;
}
}
System.out.println(succeed ? "Nice!" : "Fucking fucked!");
int[] arr = generateRandomArray(maxSize, maxValue);
printArray(arr);
heapSort(arr);
printArray(arr);
}
}
```
> å
³äºä¸è¿°heapInsertæ¹ä¸ºheapIfyçä¼åï¼
卿们ä»0å°N-1è¿è¡heapInsertçæ¶åï¼æ¯O(NlogN)ä¸åè§£éï¼å½æä»¬ä»N-1å°0ä¸ä¾æ¬¡heapifyçæ¶åï¼æ´ä½æ¥çï¼æ´æ£µæ çè·èç¹çheapify屿°N/2ï¼ç¬¬äºå±ä¸ºN/4ä¸æä¸¤ä¸ªèç¹ãé£ä¹å®è´¨æ¯N个ä¸åç屿°ç¸å ï¼
```math
T(N) = (\frac{N}{2} * 1) + (\frac{N}{4} * 2) + (\frac{N}{8} * 3) + (\frac{N}{16} * 4) + ...
=>
2T(N) = (\frac{N}{2} * 2) + (\frac{N}{2} * 2) + (\frac{N}{4} * 3) + (\frac{N}{8} * 4) + ...
=>
T(N) = N + \frac{N}{2} + \frac{N}{4} + \frac{N}{8} + ...
=> O(N)
```
1.1.6 è¯è¨ãç³»ç»æä¾çå åæåå çéæ©
>
1.1.6.1 ç³»ç»å®ç°çå
>
> ç³»ç»å®ç°çå å®è´¨ä¸å°±æ¯ä¼å
级éåï¼è½ç¶åç§°å«ä¼å
级éåï¼åºå±å°±æ¯å å®ç°çãé»è®¤æ¯å°æ ¹å ï¼æä»¬å¯ä»¥èªå®ä¹æ¯è¾å¨æå®æ¹ä¸ºå¤§æ ¹å
```Java
package class04;
import java.util.Comparator;
import java.util.PriorityQueue;
public class Test {
// è´æ°ï¼o1 æ¾å¨ä¸é¢çæ
åµ
public static class MyComp implements Comparator{
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
}
public static void main(String[] args) {
System.out.println("hello");
// å¤§æ ¹å
PriorityQueue heap = new PriorityQueue<>(new MyComp());
heap.add(5);
heap.add(7);
heap.add(3);
heap.add(0);
heap.add(2);
heap.add(5);
while(!heap.isEmpty()) {
System.out.println(heap.poll());
}
}
}
```
å çç¸å
³é¢è¯é¢ï¼
é¢ç®ä¸ï¼å·²ç¥ä¸ä¸ªå 乿åºçæ°ç»ãå ä¹æåºæ¯æï¼å¦æææ°ç»æå¥½åºçè¯ï¼æ¯ä¸ªå
ç´ ç§»å¨çè·ç¦»ä¸å®ä¸è¶
è¿kï¼å¹¶ä¸kç¸å¯¹äºæ°ç»é¿åº¦æ¥è¯´æ¯æ¯è¾å°çãè¯·éæ©ä¸ä¸ªåéçæåºçç¥ï¼å¯¹è¿ä¸ªæ°ç»è¿è¡æåº
> æè·¯ï¼ä¾å¦ç»å®ä¸ä¸ªæ°ç»ï¼k=5,é£ä¹æä»¬ä»0å¼å§ï¼åK+1个æ°ä¹å°±æ¯0å°5ä½ç½®çæ°æ¾å°å°æ ¹å ï¼æåºä¹åææå°çæ¾å°0ä½ç½®ï¼æ¥ä¸æ¥æ6ä½ç½®æ¾å°æ ¹å (æ¤æ¶å°æ ¹å é颿0å°6ä½ç½®çæ°),ç±äº0ä½ç½®çæ°æè·ç¦»éå¶åªè½ä»0å°5ä¸éæ©ï¼æä»¥æ¤æ¶å¼¹åºæå°å¼æ¾å°1ä½ç½®ï¼æ¤æ¶1ä½ç½®è¢«åºå®...
```Java
package class04;
import java.util.Arrays;
import java.util.PriorityQueue;
public class Code05_SortArrayDistanceLessK {
public static void sortedArrDistanceLessK(int[] arr, int k) {
if (k == 0) {
return;
}
// é»è®¤å°æ ¹å
PriorityQueue heap = new PriorityQueue<>();
int index = 0;
// 0...K-1
for (; index <= Math.min(arr.length - 1, k - 1); index++) {
heap.add(arr[index]);
}
int i = 0;
for (; index < arr.length; i++, index++) {
heap.add(arr[index]);
arr[i] = heap.poll();
}
while (!heap.isEmpty()) {
arr[i++] = heap.poll();
}
}
// for test
public static void comparator(int[] arr, int k) {
Arrays.sort(arr);
}
// for test
public static int[] randomArrayNoMoveMoreK(int maxSize, int maxValue, int K) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
}
// å
æä¸ªåº
Arrays.sort(arr);
// ç¶åå¼å§éæäº¤æ¢ï¼ä½æ¯ä¿è¯æ¯ä¸ªæ°è·ç¦»ä¸è¶
è¿K
// swap[i] == true, 表示iä½ç½®å·²ç»åä¸è¿äº¤æ¢
// swap[i] == false, 表示iä½ç½®æ²¡æåä¸è¿äº¤æ¢
boolean[] isSwap = new boolean[arr.length];
for (int i = 0; i < arr.length; i++) {
int j = Math.min(i + (int) (Math.random() * (K + 1)), arr.length - 1);
if (!isSwap[i] && !isSwap[j]) {
isSwap[i] = true;
isSwap[j] = true;
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
return arr;
}
// for test
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// for test
public static boolean isEqual(int[] arr1, int[] arr2) {
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
return false;
}
if (arr1 == null && arr2 == null) {
return true;
}
if (arr1.length != arr2.length) {
return false;
}
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
}
// for test
public static void printArray(int[] arr) {
if (arr == null) {
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
// for test
public static void main(String[] args) {
System.out.println("test begin");
int testTime = 500000;
int maxSize = 100;
int maxValue = 100;
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int k = (int) (Math.random() * maxSize) + 1;
int[] arr = randomArrayNoMoveMoreK(maxSize, maxValue, k);
int[] arr1 = copyArray(arr);
int[] arr2 = copyArray(arr);
sortedArrDistanceLessK(arr1, k);
comparator(arr2, k);
if (!isEqual(arr1, arr2)) {
succeed = false;
System.out.println("K : " + k);
printArray(arr);
printArray(arr1);
printArray(arr2);
break;
}
}
System.out.println(succeed ? "Nice!" : "Fucking fucked!");
}
}
```
> æ¶é´å¤æåº¦O(NlogK)
1.1.6.2 ç³»ç»å åæåå éæ©
>
> 使ç¨ç³»ç»æä¾çå ï¼å¦ææä»¬åªæ¯è¦ä¾æ¬¡æ¿æå¤§å¼ï¼é£ä¹åæå¤§æ ¹å ï¼å¦ææä»¬è¦æå°å¼æä»¬æå ç»æåæå°æ ¹å ãå°±æ¯ç®åçæä»¬æ·»å å¼ï¼æ¿å¼ï¼æä»¬å°±éæ©ç³»ç»æä¾çå
> éæ©æåå ï¼å¦æå·²ç»æ¾å°ç³»ç»å ä¸çå
ç´ ï¼å å
¥æä»¬æ ¹æ®éæ±ä¼å¨æ¾å
¥å ä¹åè¦æ¹å¨è¿äºå
ç´ çå¼ï¼ç³»ç»å å¹¶ä¸ä¿è¯å¼¹åºæ¥çä¸è¥¿æ¯æ£ç¡®çï¼è¿ä¸ªæ¶åéè¦æä»¬æå¨åä¸ä¸ªæä»¬èªå®ä¹çå ãè½ç¶åå¨é£ç§æå¥½å æ¹æäºå
ç´ è®©å
¶éæ°æåºçå ç»æï¼ä½æ¯å®è´¨ä¸å®æ¯éæ°æ«æ¯ä¸ªå
ç´ å»heapinsertï¼ä»£ä»·å¤ªé«ãæå¨æ¹åå çä¾åä¾å¦Dijkstraç®æ³å°±å卿¹åå çä¼å
```Java
package class04;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.PriorityQueue;
public class Code03_Heap02 {
// å
public static class MyHeap {
// å ç»æï¼æ°ç»å®ç°
private ArrayList heap;
// ä»»æä¸ä¸ªå
ç´ ï¼æä»¬è®°å½å®å¨æä»¬å ä¸çä½ç½®ä¿¡æ¯ï¼åå表ï¼ï¼æ¤æ¶æä»¬æ¾å°æä»¬è¦æ¹çå
ç´ çä½ç½®å°±O(1)
private HashMap indexMap;
// å 大å°
private int heapSize;
// æ¯è¾è§å
private Comparator super T> comparator;
// æé
public MyHeap(Comparator super T> com) {
heap = new ArrayList<>();
indexMap = new HashMap<>();
heapSize = 0;
comparator = com;
}
public boolean isEmpty() {
return heapSize == 0;
}
public int size() {
return heapSize;
}
public boolean contains(T key) {
return indexMap.containsKey(key);
}
public void push(T value) {
heap.add(value);
// ç±äºä¾æ¬¡æ·»å å
ç´ ï¼æ·»å è¿æ¥çå
ç´ ä½ç½®å°±æ¯heapSize
indexMap.put(value, heapSize);
heapInsert(heapSize++);
}
// å¼¹åº0å·ä½ç½®çå
ç´ ï¼è¦åæ¥å ååå
¸çæä½
public T pop() {
T ans = heap.get(0);
int end = heapSize - 1;
swap(0, end);
heap.remove(end);
indexMap.remove(ans);
heapify(0, --heapSize);
return ans;
}
// ç¨æ¥æ»¡è¶³èªå®ä¹çéæ±ï¼ç¨æ·è¦æ¹æä¸ªå
ç´ çå¼ï¼æä»¬éè¦æ¹è¿ä¹åç»§ç»ç»´æå ç»æ
public void resign(T value) {
int valueIndex = indexMap.get(value);
// æ¹åå¼ä¹åï¼æä»¬ä¸ç¡®å®æ¯å¼å大äºè¿æ¯åå°äºï¼å³ä¸ç¡®å®æ¯éè¦heapInsertè¿æ¯heapify,使¯ä¸¤ä¸ªæä½åªä¼å½ä¸ä¸ä¸ª
heapInsert(valueIndex);
heapify(valueIndex, heapSize);
}
// heapInsertæ¶ï¼éè¦ç¨æä»¬èªå·±çæ¯è¾å¨è¿è¡æ¯è¾
private void heapInsert(int index) {
while (comparator.compare(heap.get(index), heap.get((index - 1) / 2)) < 0) {
swap(index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
private void heapify(int index, int heapSize) {
int left = index * 2 + 1;
while (left < heapSize) {
int largest = left + 1 < heapSize && (comparator.compare(heap.get(left + 1), heap.get(left)) < 0)
? left + 1
: left;
largest = comparator.compare(heap.get(largest), heap.get(index)) < 0 ? largest : index;
if (largest == index) {
break;
}
swap(largest, index);
index = largest;
left = index * 2 + 1;
}
}
// æ¯æ¬¡äº¤æ¢ï¼ä¸ç»è¦äº¤æ¢å ä¸ä¸¤ä¸ªä½ç½®çå
ç´ ï¼å¨æä»¬çåå
¸ä¸ä¹è¦è¦æ¢ä½ç½®
private void swap(int i, int j) {
T o1 = heap.get(i);
T o2 = heap.get(j);
heap.set(i, o2);
heap.set(j, o1);
indexMap.put(o1, j);
indexMap.put(o2, i);
}
}
public static class Student {
public int classNo;
public int age;
public int id;
public Student(int c, int a, int i) {
classNo = c;
age = a;
id = i;
}
}
public static class StudentComparator implements Comparator {
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
public static void main(String[] args) {
Student s1 = null;
Student s2 = null;
Student s3 = null;
Student s4 = null;
Student s5 = null;
Student s6 = null;
s1 = new Student(2, 50, 11111);
s2 = new Student(1, 60, 22222);
s3 = new Student(6, 10, 33333);
s4 = new Student(3, 20, 44444);
s5 = new Student(7, 72, 55555);
s6 = new Student(1, 14, 66666);
PriorityQueue heap = new PriorityQueue<>(new StudentComparator());
heap.add(s1);
heap.add(s2);
heap.add(s3);
heap.add(s4);
heap.add(s5);
heap.add(s6);
while (!heap.isEmpty()) {
Student cur = heap.poll();
System.out.println(cur.classNo + "," + cur.age + "," + cur.id);
}
System.out.println("===============");
MyHeap myHeap = new MyHeap<>(new StudentComparator());
myHeap.push(s1);
myHeap.push(s2);
myHeap.push(s3);
myHeap.push(s4);
myHeap.push(s5);
myHeap.push(s6);
while (!myHeap.isEmpty()) {
Student cur = myHeap.pop();
System.out.println(cur.classNo + "," + cur.age + "," + cur.id);
}
System.out.println("===============");
s1 = new Student(2, 50, 11111);
s2 = new Student(1, 60, 22222);
s3 = new Student(6, 10, 33333);
s4 = new Student(3, 20, 44444);
s5 = new Student(7, 72, 55555);
s6 = new Student(1, 14, 66666);
heap = new PriorityQueue<>(new StudentComparator());
heap.add(s1);
heap.add(s2);
heap.add(s3);
heap.add(s4);
heap.add(s5);
heap.add(s6);
s2.age = 6;
s4.age = 12;
s5.age = 10;
s6.age = 84;
while (!heap.isEmpty()) {
Student cur = heap.poll();
System.out.println(cur.classNo + "," + cur.age + "," + cur.id);
}
System.out.println("===============");
s1 = new Student(2, 50, 11111);
s2 = new Student(1, 60, 22222);
s3 = new Student(6, 10, 33333);
s4 = new Student(3, 20, 44444);
s5 = new Student(7, 72, 55555);
s6 = new Student(1, 14, 66666);
myHeap = new MyHeap<>(new StudentComparator());
myHeap.push(s1);
myHeap.push(s2);
myHeap.push(s3);
myHeap.push(s4);
myHeap.push(s5);
myHeap.push(s6);
s2.age = 6;
myHeap.resign(s2);
s4.age = 12;
myHeap.resign(s4);
s5.age = 10;
myHeap.resign(s5);
s6.age = 84;
myHeap.resign(s6);
while (!myHeap.isEmpty()) {
Student cur = myHeap.pop();
System.out.println(cur.classNo + "," + cur.age + "," + cur.id);
}
// 对æ°å¨
System.out.println("test begin");
int maxValue = 100000;
int pushTime = 1000000;
int resignTime = 100;
MyHeap test = new MyHeap<>(new StudentComparator());
ArrayList list = new ArrayList<>();
for(int i = 0 ; i < pushTime; i++) {
Student cur = new Student(1,(int) (Math.random() * maxValue), 1000);
list.add(cur);
test.push(cur);
}
for(int i = 0 ; i < resignTime; i++) {
int index = (int)(Math.random() * pushTime);
list.get(index).age = (int) (Math.random() * maxValue);
test.resign(list.get(index));
}
int preAge = Integer.MIN_VALUE;
while(test.isEmpty()) {
Student cur = test.pop();
if(cur.age < preAge) {
System.out.println("Oops!");
}
preAge = cur.age;
}
System.out.println("test finish");
}
}
```
1.2 æ¯è¾å¨
>
1ãæ¯è¾å¨çå®è´¨å°±æ¯éè½½æ¯è¾è¿ç®ç¬¦
2ãæ¯è¾å¨å¯ä»¥å¾å¥½çåºç¨å¨ç¹æ®æ åçæåºä¸
3ãæ¯è¾å¨å¯ä»¥å¾å¥½çåºç¨å¨æ ¹æ®ç¹æ®æ åæåºçç»æä¸
> 任使åºç»æï¼æä»¬å¯ä»¥ä¼ å
¥æä»¬çæ¯è¾å¨ï¼èªå®ä¹æä»¬èªå·±çæåºè§åï¼ä¸ä¼ å®ä¼æèªå·±é»è®¤çè§åæåº
4ãå代ç åå¾å¼å¸¸å®¹æï¼è¿ç¨äºæ³åç¼ç¨
> æ¯è¾è§åä¸o1,o2ï¼æ¯è¾å¨è¿åè´æ°è¡¨ç¤ºo1è¦æå¨åé¢ï¼è¿åæ£æ°è¡¨ç¤ºo1è¦æå¨åé¢ï¼è¿å0表示o1åo1ç¸çæ éæåºãå¨javaä¸èªå®ä¹çæ¯è¾å¨ï¼MyComparatorï¼å®ç°Comparatoræ¥å£ï¼å®ç°è¯¥æ¥å£ä¸çcompareæ¹æ³ï¼èªå®ä¹æä»¬çæ¯è¾è§åã
> 使ç¨ç¤ºä¾ï¼Arrays.sort(student, new MyComparator())
```Java
package class04;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.TreeSet;
public class Code01_Comparator {
// èªå®ä¹æä»¬çæåºå¯¹è±¡
public static class Student {
public String name;
public int id;
public int age;
public Student(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
}
public static class IdAscendingComparator
implements Comparator {
// è¿åè´æ°çæ¶åï¼ç¬¬ä¸ä¸ªåæ°æå¨åé¢
// è¿åæ£æ°çæ¶åï¼ç¬¬äºä¸ªåæ°æå¨åé¢
// è¿å0çæ¶åï¼è°å¨å颿 æè°
@Override
public int compare(Student o1, Student o2) {
return o1.id - o2.id;
}
}
public static class IdDescendingComparator implements Comparator {
@Override
public int compare(Student o1, Student o2) {
return o2.id - o1.id;
}
}
public static class AgeAscendingComparator implements Comparator {
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
public static class AgeDescendingComparator implements Comparator {
@Override
public int compare(Student o1, Student o2) {
return o2.age - o1.age;
}
}
public static class AgeShengIdSheng implements Comparator {
@Override
public int compare(Student o1, Student o2) {
return o1.age != o2.age ? (o1.age - o2.age)
: (o1.id - o2.id);
}
}
// å
æç
§idæåºï¼idå°çï¼æ¾åé¢ï¼
// id䏿 ·ï¼age大çï¼åé¢ï¼
public static class IdInAgeDe implements Comparator {
@Override
public int compare(Student o1, Student o2) {
return o1.id != o2.id ? o1.id - o2.id : ( o2.age - o1.age );
}
}
public static void printStudents(Student[] students) {
for (Student student : students) {
System.out.println("Name : " + student.name + ", Id : " + student.id + ", Age : " + student.age);
}
}
public static void printArray(Integer[] arr) {
if (arr == null) {
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static class MyComp implements Comparator {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
}
public static class AComp implements Comparator{
// 妿è¿åè´æ°ï¼è®¤ä¸ºç¬¬ä¸ä¸ªåæ°åºè¯¥æå¨åé¢
// 妿è¿åæ£æ°ï¼è®¤ä¸ºç¬¬äºä¸ªåæ°åºè¯¥æå¨åé¢
// 妿è¿å0ï¼è®¤ä¸ºè°æ¾åé¢é½è¡
@Override
public int compare(Integer arg0, Integer arg1) {
return arg1 - arg0;
// return 0;
}
}
public static void main(String[] args) {
Integer[] arr = {5,4,3,2,7,9,1,0};
Arrays.sort(arr, new AComp());
for(int i = 0 ;i < arr.length;i++) {
System.out.println(arr[i]);
}
System.out.println("===========================");
Student student1 = new Student("A", 2, 20);
Student student2 = new Student("B", 3, 21);
Student student3 = new Student("C", 1, 22);
Student[] students = new Student[] { student1, student2, student3 };
System.out.println("ç¬¬ä¸æ¡æå°");
Arrays.sort(students, new IdAscendingComparator());
printStudents(students);
System.out.println("===========================");
Arrays.sort(students, new IdDescendingComparator());
printStudents(students);
System.out.println("===========================");
Arrays.sort(students, new AgeAscendingComparator());
printStudents(students);
System.out.println("===========================");
////
//// Arrays.sort(students, new AgeDescendingComparator());
//// printStudents(students);
//// System.out.println("===========================");
//
// Arrays.sort(students, new AgeShengIdSheng());
// printStudents(students);
//
// System.out.println("===========================");
// System.out.println("===========================");
// System.out.println("===========================");
//
// PriorityQueue maxHeapBasedAge = new PriorityQueue<>(new AgeDescendingComparator());
// maxHeapBasedAge.add(student1);
// maxHeapBasedAge.add(student2);
// maxHeapBasedAge.add(student3);
// while (!maxHeapBasedAge.isEmpty()) {
// Student student = maxHeapBasedAge.poll();
// System.out.println("Name : " + student.name + ", Id : " + student.id + ", Age : " + student.age);
// }
// System.out.println("===========================");
PriorityQueue minHeapBasedId
= new PriorityQueue<>(new AgeAscendingComparator());
minHeapBasedId.add(student1);
minHeapBasedId.add(student2);
minHeapBasedId.add(student3);
while (!minHeapBasedId.isEmpty()) {
Student student = minHeapBasedId.poll();
System.out.println("Name : " + student.name + ", Id : " + student.id + ", Age : " + student.age);
}
System.out.println("===========================");
System.out.println("===========================");
System.out.println("===========================");
TreeSet treeAgeDescending = new TreeSet<>(new AgeAscendingComparator());
treeAgeDescending.add(student1);
treeAgeDescending.add(student2);
treeAgeDescending.add(student3);
Student studentFirst = treeAgeDescending.first();
System.out.println("Name : " + studentFirst.name + ", Id : " + studentFirst.id + ", Age : " + studentFirst.age);
Student studentLast = treeAgeDescending.last();
System.out.println("Name : " + studentLast.name + ", Id : " + studentLast.id + ", Age : " + studentLast.age);
System.out.println("===========================");
}
}
```