- [1 å¹¶æ¥éãå¾ç¸å
³ç®æ³](#1)
* [1.1 å¹¶æ¥é](#11)
+ [1.1.1 å¹¶æ¥éåºæ¬ç»æåæä½](#111)
+ [1.1.2 ä¾é¢](#112)
* [1.2 å¾ç¸å
³ç®æ³](#12)
+ [1.2.1 å¾çæ¦å¿µ](#121)
+ [1.2.2 å¾çè¡¨ç¤ºæ¹æ³](#122)
- [1.2.2.1 黿¥è¡¨è¡¨ç¤ºæ³](#1221)
- [1.2.2.2 黿¥ç©éµè¡¨ç¤ºæ³](#1222)
+ [1.2.3 å¾çéå](#123)
- [1.2.3.1 宽度ä¼å
éå](#1231)
- [1.2.3.2 深度ä¼å
éå](#1232)
+ [1.2.4 å¾çæææåº](#124)
+ [1.2.5 å¾çæå°çææ ç®æ³](#125)
- [1.2.5.1 Kruskalï¼å
鲿¯å¡å°ï¼ç®æ³](#1251)
- [1.2.5.2 Primç®æ³](#1252)
+ [1.2.6 å¾çæçè·¯å¾ç®æ³](#126)
- [1.2.6.1 Dijkstra(迪æ°ç¹æ¯æ)ç®æ³](#1261)
- [1.2.6.2 floydç®æ³](#1262)
1 å¹¶æ¥éãå¾ç¸å
³ç®æ³
1.1 å¹¶æ¥é
1.1.1 å¹¶æ¥éåºæ¬ç»æåæä½
1ãæè¥å¹²ä¸ªæ ·æ¬aãbãcãd...ç±»åå设æ¯V
2ãå¨å¹¶æ¥éä¸ä¸å¼å§è®¤ä¸ºæ¯ä¸ªæ ·æ¬é½å¨åç¬çéåé
3ãç¨æ·å¯ä»¥å¨ä»»ä½æ¶åè°ç¨å¦ä¸ä¸¤ä¸ªæ¹æ³ï¼
boolean isSameSet(V x, V y)ï¼æ¥è¯¢æ ·æ¬xåæ ·æ¬yæ¯å¦å±äºä¸ä¸ªéå
void union(V x, V y)ï¼æxåyåèªæå¨éåçæææ ·æ¬åå¹¶æä¸ä¸ªéå
4ãisSameSetåunionæ¹æ³ç代价è¶ä½è¶å¥½ï¼æå¥½O(1)
> æè·¯ï¼isSameSetæ¹æ³ï¼æä»¬è®¾è®¡ä¸ºæ¯ä¸ªå
ç´ æä¸ä¸ªæåèªå·±çæéï¼æä¸ºä»£è¡¨ç¹ãå¤æä¸¤ä¸ªå
ç´ æ¯å¦å¨ä¸ä¸ªéåä¸ï¼åå«è°ç¨è¿ä¸¤ä¸ªå
ç´ çå䏿éï¼ä¸¤ä¸ªå
ç´ æä¸æ¹çæé妿å
åå°åç¸åï¼é£ä¹ä¸¤ä¸ªå
ç´ å¨ä¸ä¸ªéåä¸ï¼åä¹ä¸å¨
> æè·¯ï¼unionæ¹æ³ï¼ä¾å¦å°aæå¨çéååeæå¨çéååå¹¶æä¸ä¸ªå¤§çéåunion(a,e)ãaçä»£è¡¨ç¹æéæ¯aï¼eçä»£è¡¨ç¹æéæ¯eï¼æä»¬æ¿è¾å°çéåæå¨å¤§çéåä¸é¢ï¼æ¯å¦eå°ï¼é£ä¹eæ¾å¨açä¸é¢ã龿¥çæ¹å¼ä¸ºå°éåe头ç»ç¹æ¬æ¥æåèªå·±ç代表èç¹ï¼ç°å¨è¦æåaèç¹
> å¹¶æ¥éçä¼åç¹ä¸»è¦æä¸¤ä¸ªï¼ä¸ä¸ªæ¯åå¹¶çæ¶åå°çéåæå¨å¤§çéåä¸é¢ï¼ç¬¬äºä¸ªä¼åæ¯æ¾æèç¹æä¸æ¹ç代表èç¹ï¼ææ²¿éèç¹å
¨é¨æå¹³ï¼ä¸æ¬¡åæ¾è¯¥æ²¿éèç¹ï¼é½å为O(1)ã两ç§ä¼åçç®ç齿¯ä¸ºäºæ´å°çéåèç¹ã
> ç±äºæä»¬å å
¥äºä¼åï¼å¦æN个èç¹ï¼æä»¬è°ç¨findFatherè¶é¢ç¹ï¼æä»¬çæ¶é´å¤æåº¦è¶ä½ï¼å ä¸ºç¬¬ä¸æ¬¡è°ç¨æä»¬å å
¥äºä¼åã妿findFatherè°ç¨æ¥è¿N次æè
è¿è¿è¶
è¿Næ¬¡ï¼æä»¬å¹¶æ¥éçæ¶é´å¤æåº¦å°±æ¯O(1)ãè¯¥å¤æåº¦åªéè¦è®°ä½ç»è®ºï¼è¯ææ é¡»ææ¡ãè¯¥è¯æä»1964å¹´ä¸ç´ç ç©¶å°1989å¹´ï¼æ´æ´25å¹´æå¾åºè¯æï¼ç®æ³å¯¼è®º23ç« ï¼è±æçæ¥è¿50页çè¯æã
```Java
package class10;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
public class Code01_UnionFind {
// å¹¶æ¥éç»æä¸çèç¹ç±»å
public static class Node {
V value;
public Node(V v) {
value = v;
}
}
public static class UnionSet {
// è®°å½æ ·æ¬å°æ ·æ¬ä»£è¡¨ç¹çå
³ç³»
public HashMap> nodes;
// è®°å½æèç¹å°ç¶äº²èç¹çå
³ç³»ã
// æ¯å¦bæåaï¼cæåaï¼dæåaï¼aæåèªèº«
// mapä¸ä¿åça->a b->a c->a d->a
public HashMap, Node> parents;
// åªæå½åç¹ï¼ä»æ¯ä»£è¡¨ç¹ï¼ä¼å¨sizeMapä¸è®°å½è¯¥ä»£è¡¨ç¹çè¿é个æ°
public HashMap, Integer> sizeMap;
// åå§åæé 䏿¹æ ·æ¬
public UnionSet(List values) {
// æ¯ä¸ªæ ·æ¬çVæåèªèº«ç代表èç¹
// æ¯ä¸ªæ ·æ¬å½å齿¯ç¬ç«çï¼parentæ¯èªèº«
// æ¯ä¸ªæ ·æ¬é½æ¯ä»£è¡¨èç¹æ¾å
¥sizeMap
for (V cur : values) {
Node node = new Node<>(cur);
nodes.put(cur, node);
parents.put(node, node);
sizeMap.put(node, 1);
}
}
// ä»ç¹curå¼å§ï¼ä¸ç´å¾ä¸æ¾ï¼æ¾å°ä¸è½åå¾ä¸ç代表ç¹ï¼è¿å
// éè¿æè·¯å¾ä¸ææèç¹æåæä¸æ¹ç代表èç¹ï¼ç®çæ¯æfindFatherä¼åæO(1)ç
public Node findFather(Node cur) {
// 卿¾fatherçè¿ç¨ä¸ï¼æ²¿éææèç¹å å
¥å½å容å¨ï¼ä¾¿äºå颿平åå¤ç
Stack> path = new Stack<>();
// å½åèç¹çç¶äº²ä¸æ¯æåèªå·±ï¼è¿è¡å¾ªç¯
while (cur != parents.get(cur)) {
path.push(cur);
cur = parents.get(cur);
}
// 循ç¯ç»æï¼curæ¯æä¸ç代表èç¹
// ææ²¿éææèç¹æå¹³ï¼é½æåå½åæä¸æ¹ç代表èç¹
while (!path.isEmpty()) {
parents.put(path.pop(), cur);
}
return cur;
}
// isSameSetæ¹æ³
public boolean isSameSet(V a, V b) {
// å
æ£æ¥aåbææ²¡æç»è®°
if (!nodes.containsKey(a) || !nodes.containsKey(b)) {
return false;
}
// æ¯è¾açæä¸ç代表ç¹åbæä¸ç代表ç¹
return findFather(nodes.get(a)) == findFather(nodes.get(b));
}
// unionæ¹æ³
public void union(V a, V b) {
// å
æ£æ¥aåbææ²¡æé½ç»è®°è¿
if (!nodes.containsKey(a) || !nodes.containsKey(b)) {
return;
}
// æ¾å°açæä¸é¢ç代表ç¹
Node aHead = findFather(nodes.get(a));
// æ¾å°bçæä¸é¢ç代表ç¹
Node bHead = findFather(nodes.get(b));
// åªæä¸¤ä¸ªæä¸ä»£è¡¨ç¹å
åå°åä¸ç¸åï¼éè¦union
if (aHead != bHead) {
// ç±äºaHeadåbHead齿¯ä»£è¡¨ç¹ï¼é£ä¹å¨sizeMapéå¯ä»¥æ¿å°å¤§å°
int aSetSize = sizeMap.get(aHead);
int bSetSize = sizeMap.get(bHead);
// åªä¸ªå°ï¼åªä¸ªæå¨ä¸é¢
Node big = aSetSize >= bSetSize ? aHead : bHead;
Node small = big == aHead ? bHead : aHead;
// æå°éåç´æ¥æå°å¤§éåçæä¸é¢ç代表èç¹ä¸é¢
parents.put(small, big);
// 大éåç代表èç¹çsizeè¦å¸æ¶æå°éåçsize
sizeMap.put(big, aSetSize + bSetSize);
// æå°çè®°å½å é¤
sizeMap.remove(small);
}
}
}
}
```
==å¹¶æ¥éç¨æ¥å¤çè¿éæ§çé®é¢ç¹å«æ¹ä¾¿==
1.1.2 ä¾é¢
å¦çå®ä¾æä¸ä¸ªå±æ§ï¼èº«ä»½è¯ä¿¡æ¯ï¼Bç«ID,GithubçIdãæä»¬è®¤ä¸ºï¼ä»»ä½ä¸¤ä¸ªå¦çå®ä¾ï¼åªè¦èº«ä»½è¯ä¸æ ·ï¼æè
Bç«ID䏿 ·ï¼æè
GithubçId䏿 ·ï¼æä»¬é½ç®ä¸ä¸ªäººãç»å®ä¸ææ¼å¦çå®ä¾ï¼è¾åºæå®è´¨æå 个人ï¼
> æè·¯ï¼æå®ä¾çä¸ä¸ªå±æ§å»ºç«ä¸å¼ æ å°è¡¨ï¼æ¯ä¸ªå®ä¾å»å¯¹æ¯ï¼æä¸ªå®ä¾å±æ§å¨è¡¨ä¸è½æ¥çå°ï¼éè¦èé该å®ä¾å°ä¹åä¿å该å®ä¾å±æ§ç头ç»ç¹ä¸
```Java
package class10;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
public class Code07_MergeUsers {
public static class Node {
V value;
public Node(V v) {
value = v;
}
}
public static class UnionSet {
public HashMap> nodes;
public HashMap, Node> parents;
public HashMap, Integer> sizeMap;
public UnionSet(List values) {
for (V cur : values) {
Node node = new Node<>(cur);
nodes.put(cur, node);
parents.put(node, node);
sizeMap.put(node, 1);
}
}
// ä»ç¹curå¼å§ï¼ä¸ç´å¾ä¸æ¾ï¼æ¾å°ä¸è½åå¾ä¸ç代表ç¹ï¼è¿å
public Node findFather(Node cur) {
Stack> path = new Stack<>();
while (cur != parents.get(cur)) {
path.push(cur);
cur = parents.get(cur);
}
// cur头èç¹
while (!path.isEmpty()) {
parents.put(path.pop(), cur);
}
return cur;
}
public boolean isSameSet(V a, V b) {
if (!nodes.containsKey(a) || !nodes.containsKey(b)) {
return false;
}
return findFather(nodes.get(a)) == findFather(nodes.get(b));
}
public void union(V a, V b) {
if (!nodes.containsKey(a) || !nodes.containsKey(b)) {
return;
}
Node aHead = findFather(nodes.get(a));
Node bHead = findFather(nodes.get(b));
if (aHead != bHead) {
int aSetSize = sizeMap.get(aHead);
int bSetSize = sizeMap.get(bHead);
Node big = aSetSize >= bSetSize ? aHead : bHead;
Node small = big == aHead ? bHead : aHead;
parents.put(small, big);
sizeMap.put(big, aSetSize + bSetSize);
sizeMap.remove(small);
}
}
public int getSetNum() {
return sizeMap.size();
}
}
public static class User {
public String a;
public String b;
public String c;
public User(String a, String b, String c) {
this.a = a;
this.b = b;
this.c = c;
}
}
// (1,10,13) (2,10,37) (400,500,37)
// å¦æä¸¤ä¸ªuserï¼aåæ®µä¸æ ·ãæè
båæ®µä¸æ ·ãæè
cåæ®µä¸æ ·ï¼å°±è®¤ä¸ºæ¯ä¸ä¸ªäºº
// 请åå¹¶usersï¼è¿ååå¹¶ä¹åçç¨æ·æ°é
public static int mergeUsers(List users) {
UnionSet unionFind = new UnionSet<>(users);
HashMap mapA = new HashMap<>();
HashMap mapB = new HashMap<>();
HashMap mapC = new HashMap<>();
for(User user : users) {
if(mapA.containsKey(user.a)) {
unionFind.union(user, mapA.get(user.a));
}else {
mapA.put(user.a, user);
}
if(mapB.containsKey(user.b)) {
unionFind.union(user, mapB.get(user.b));
}else {
mapB.put(user.b, user);
}
if(mapC.containsKey(user.c)) {
unionFind.union(user, mapC.get(user.c));
}else {
mapC.put(user.c, user);
}
}
// åå¹¶æ¥é询é®ï¼åå¹¶ä¹åï¼è¿æå¤å°ä¸ªéåï¼
return unionFind.getSetNum();
}
}
```
1.2 å¾ç¸å
³ç®æ³
1.2.1 å¾çæ¦å¿µ
1ãç±ç¹çéååè¾¹çéåææ
2ãè½ç¶å卿åå¾åæ åå¾çæ¦å¿µï¼ä½å®é
ä¸é½å¯ä»¥ç¨æå徿¥è¡¨è¾¾ï¼æ åå¾å¯ä»¥ç解为两个èéç¹äºç¸æå
3ãè¾¹ä¸å¯è½å¸¦ææå¼
1.2.2 å¾çè¡¨ç¤ºæ¹æ³
对äºä¸é¢ä¸å¼ æ åå¾ï¼å¯ä»¥æ¹ä¸ºæåå¾ï¼
```
graph LR;
A-->C
C-->A
C-->B
B-->C
B-->D
D-->B
D-->A
A-->D
```
1.2.2.1 黿¥è¡¨è¡¨ç¤ºæ³
è®°å½æä¸ªèç¹ï¼ç´æ¥å°è¾¾çé»å±
èç¹ï¼
A: C,D
B: C,D
C: A,B
D: B,A
妿æ¯å¸¦ææéçè¾¹ï¼å¯ä»¥å°è£
æä»¬çç»æï¼ä¾å¦Aå°Cçæéæ¯3,é£ä¹æä»¬å¯ä»¥è¡¨ç¤ºä¸ºA: C(3),D
1.2.2.2 黿¥ç©éµè¡¨ç¤ºæ³
æä»¬æä¸åå¨è·¯å¾çç¨æ£æ 穷表示ï¼è¿éç¨'-'表示ï¼ä¾å¦Aå°Cçè¾¹æéæ¯3ï¼å¯æä¸å¾è¡¨ç¤ºä¸ºï¼
```
A B C D
A 0 0 3 -
B - 0 0 0
C 3 0 0 -
D 0 0 - 0
```
> å¾ç®æ³å¹¶ä¸é¾ï¼é¾ç¹å¨äºå¾æå¾å¤ç§è¡¨ç¤ºæ¹å¼ï¼è¡¨è¾¾ä¸å¼ å¾çç¯å¹
æ¯è¾å¤§ï¼coding容æåºéãæä»¬çå¥è·¯å°±æ¯çæä¸ç§ç»æï¼éå°ä¸åç表达æ¹å¼ï¼å°è¯è½¬åæä¸ºæä»¬çæçç»æï¼è¿è¡æä½
ç¹ç»æçæè¿°ï¼
```Java
package class10;
import java.util.ArrayList;
// ç¹ç»æçæè¿° A 0
public class Node {
// ç¹çç¼å·ï¼æ è¯
public int value;
// å
¥åº¦ï¼è¡¨ç¤ºæå¤å°ä¸ªç¹è¿å该ç¹
public int in;
// åºåº¦ï¼è¡¨ç¤ºä»è¯¥ç¹åºåè¿åå«çèç¹å¤å°
public int out;
// ç´æ¥é»å±
ï¼è¡¨ç¤ºç±èªå·±åºåï¼ç´æ¥æååªäºèç¹ãnexts.size==out
public ArrayList nexts;
// ç´æ¥ä¸çº§è¾¹ï¼è¡¨ç¤ºç±èªå·±åºåçè¾¹æå¤å°
public ArrayList edges;
public Node(int value) {
this.value = value;
in = 0;
out = 0;
nexts = new ArrayList<>();
edges = new ArrayList<>();
}
}
```
è¾¹ç»æçæè¿°ï¼
```Java
package class10;
// ç±äºä»»ä½å¾é½å¯ä»¥ç解为æåå¾ï¼æä»¬å®ä¹æåçè¾¹ç»æ
public class Edge {
// è¾¹çæéä¿¡æ¯
public int weight;
// åºåçèç¹
public Node from;
// æåçèç¹
public Node to;
public Edge(int weight, Node from, Node to) {
this.weight = weight;
this.from = from;
this.to = to;
}
}
```
å¾ç»æçæè¿°ï¼
```Java
package class10;
import java.util.HashMap;
import java.util.HashSet;
// å¾ç»æ
public class Graph {
// ç¹çéåï¼ç¼å·ä¸º1çç¹æ¯ä»ä¹ï¼ç¨map
public HashMap nodes;
// è¾¹çéå
public HashSet edges;
public Graph() {
nodes = new HashMap<>();
edges = new HashSet<>();
}
}
```
ä»»æå¾ç»æçæè¿°ï¼åæä»¬ä¸è¿°çå¾ç»æè½¬åï¼
ä¾å¦ï¼æä»¬æä¸ç§å¾çæè¿°æ¯ï¼åçæéï¼ä»fromèç¹æåtoèç¹
```Java
package class10;
public class GraphGenerator {
// matrix ææçè¾¹
// N*3 çç©éµ
// [weight, fromèç¹ä¸é¢çå¼ï¼toèç¹ä¸é¢çå¼]
public static Graph createGraph(Integer[][] matrix) {
// å®ä¹æä»¬çå¾ç»æ
Graph graph = new Graph();
// éåç»å®çå¾ç»æè¿è¡è½¬æ¢
for (int i = 0; i < matrix.length; i++) {
// matrix[0][0], matrix[0][1] matrix[0][2]
Integer weight = matrix[i][0];
Integer from = matrix[i][1];
Integer to = matrix[i][2];
// æä»¬çå¾ç»æä¸å
å«å½åfromèç¹ï¼æ°å»ºè¯¥èç¹
if (!graph.nodes.containsKey(from)) {
graph.nodes.put(from, new Node(from));
}
// 没ætoèç¹ï¼å»ºç«è¯¥èç¹
if (!graph.nodes.containsKey(to)) {
graph.nodes.put(to, new Node(to));
}
// æ¿åºæä»¬å¾ç»æçfromèç¹
Node fromNode = graph.nodes.get(from);
// æ¿åºæä»¬å¾ç»æçtoèç¹
Node toNode = graph.nodes.get(to);
// å»ºç«æä»¬çè¾¹ç»æãæéï¼fromæåto
Edge newEdge = new Edge(weight, fromNode, toNode);
// ætoèç¹å å
¥å°fromèç¹çç´æ¥é»å±
ä¸
fromNode.nexts.add(toNode);
// fromçåºåº¦å 1
fromNode.out++;
// toçå
¥åº¦å 1
toNode.in++;
// 该边éè¦æ¾å°fromçç´æ¥è¾¹çéåä¸
fromNode.edges.add(newEdge);
// æè¯¥è¾¹å å
¥å°æä»¬å¾ç»æçè¾¹éä¸
graph.edges.add(newEdge);
}
return graph;
}
}
```
1.2.3 å¾çéå
ä¾å¦è¯¥å¾ï¼
```
graph LR;
A-->B
A-->C
A-->D
B-->C
B-->E
C-->A
C-->B
C-->D
C-->E
```
1.2.3.1 宽度ä¼å
éå
1ãå©ç¨éåå®ç°
2ã仿ºèç¹å¼å§ä¾æ¬¡æç
§å®½åº¦è¿éåï¼ç¶åå¼¹åº
3ãæ¯å¼¹åºä¸ä¸ªç¹ï¼æè¯¥èç¹æææ²¡æè¿è¿éåç黿¥ç¹æ¾å
¥éå
4ãç´å°éåå空
> 宽度ä¼å
çæè·¯ï¼å®è´¨å
éåèªå·±ï¼åéåèªå·±çä¸ä¸è·³èç¹(åä¸å±èç¹çé¡ºåºæ éå
³ç³»)ï¼åä¸ä¸è·³èç¹......
æä»¬ä»Aç¹å¼å§éåï¼
1ãAè¿éå--> Q[A]ï¼Aè¿å
¥Set--> S[A]
2ãAåºéï¼Q[],**æå°A**ï¼Aç´æ¥é»å±
为BCD,é½ä¸å¨Setä¸ï¼è¿å
¥éåQ[D,C,B], è¿å
¥S[A,B,C,D]
3ãBåºéï¼Q[D,C], BæCEä¸ä¸ªé»å±
ï¼Cå·²ç»å¨Setä¸, æ¾å
¥E, S[A,B,C,D,E]ï¼éåæ¾E, Q[E,D,C]
4ã Cåºéï¼å¨èå¤å§
```Java
package class10;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
public class Code02_BFS {
// ä»nodeåºåï¼è¿è¡å®½åº¦ä¼å
éå
public static void bfs(Node node) {
if (node == null) {
return;
}
Queue queue = new LinkedList<>();
// å¾éè¦ç¨setç»æï¼å 为å¾ç¸æ¯äºäºåæ æå¯è½åå¨ç¯
// 峿å¯è½åå¨æä¸ªç¹å¤æ¬¡è¿å
¥éåçæ
åµ
HashSet set = new HashSet<>();
queue.add(node);
set.add(node);
while (!queue.isEmpty()) {
Node cur = queue.poll();
System.out.println(cur.value);
for (Node next : cur.nexts) {
// ç´æ¥é»å±
ï¼æ²¡æè¿å
¥è¿Setçè¿å
¥Setåéå
// ç¨setéå¶éåçå
ç´ ï¼é²æ¢æç¯éåä¸ç´ä¼å å
¥å
ç´
if (!set.contains(next)) {
set.add(next);
queue.add(next);
}
}
}
}
}
```
1.2.3.2 深度ä¼å
éå
1ãå©ç¨æ å®ç°
2ã仿ºèç¹å¼å§æèç¹æç
§æ·±åº¦æ¾å
¥æ ï¼ç¶åå¼¹åº
3ãæ¯å¼¹åºä¸ä¸ªç¹ï¼æè¯¥èç¹ä¸ä¸ä¸ªæ²¡æè¿è¿æ ç黿¥ç¹æ¾å
¥æ
4ãç´å°æ å空
> 深度ä¼å
æè·¯ï¼è¡¨ç¤ºä»æä¸ªèç¹ä¸ç´å¾ä¸æ·±å
¥ï¼ç¥é没æè·¯äºï¼è¿åãæä»¬çæ å®è´¨è®°å½çæ¯æä»¬æ·±åº¦ä¼å
éåçè·¯å¾
æä»¬ä»Aç¹å¼å§éåï¼
1ãAè¿æ ï¼Stack[A] **æå°A**ãå¼¹åºAï¼å½åå¼¹åºçèç¹A廿䏾å®çå代BCDï¼B没å å
¥è¿æ ä¸ãåå
¥Aååå
¥B,Stack[B,A]ã**æå°B**
2ãå¼¹åºB,Bçç´æ¥å代é»å±
为CE,Cåæ ä¸èEä¸å¨æ ä¸ãéæ°åB,åEï¼Stack[E,B,A]ã**æå°E**
3ãå¼¹åºE,Eæé»å±
D,Dä¸å¨æ ä¸ãååEï¼ååD,æ¤æ¶Stack[D,E,B,A]ã**æå°D**
4ã å¼¹åºD,Dçç´æ¥é»å±
æ¯A,Aå·²ç»å¨æ ä¸äºã说æA-B-E-Dè¿æ¡è·¯å¾èµ°å°äºå°½å¤´ãå¼¹åºDä¹åï¼å½å循ç¯ç»æãç»§ç»whileæ ä¸ä¸ºç©ºï¼é夿ä½
```Java
package class10;
import java.util.HashSet;
import java.util.Stack;
public class Code02_DFS {
public static void dfs(Node node) {
if (node == null) {
return;
}
Stack stack = new Stack<>();
// Setçä½ç¨å宽度ä¼å
éå类似ï¼ä¿è¯éå¤çç¹ä¸è¦è¿æ
HashSet set = new HashSet<>();
stack.add(node);
set.add(node);
// æå°å®æ¶æºæ¯å¨è¿æ çæ¶å
// åç该æ¥å¯ä»¥æ¢æå
¶ä»å¤çé»è¾ï¼è¡¨ç¤ºæ·±åº¦éåå¤çæä»¶äºæ
System.out.println(node.value);
while (!stack.isEmpty()) {
Node cur = stack.pop();
// æä¸¾å½åå¼¹åºèç¹çå代
for (Node next : cur.nexts) {
// åªè¦æä¸ªå代没è¿å
¥è¿æ ï¼è¿æ
if (!set.contains(next)) {
// æè¯¥èç¹çç¶äº²èç¹éæ°ååæ ä¸
stack.push(cur);
// åæèªå·±åå
¥æ ä¸
stack.push(next);
set.add(next);
// æå°å½åèç¹çå¼
System.out.println(next.value);
// ç´æ¥breakï¼æ¤æ¶æ é¡¶æ¯å½ånextèç¹ï¼è¾¾å°æ·±åº¦ä¼å
çç®ç
break;
}
}
}
}
}
```
1.2.4 å¾çæææåº
1ãå¨å¾ä¸æ¾å°ææå
¥åº¦ä¸º0çç¹è¾åº
2ãæææå
¥åº¦ä¸º0çç¹å¨å¾ä¸å æï¼åæ¶é¤è¿äºç¹çå½±åè¾¹ãç»§ç»æ¾å
¥åº¦ä¸º0çç¹è¾åºï¼å é¤ï¼æ¶è¾¹ï¼å¨èå¤å§
3ãå¾çææç¹é½è¢«å é¤åï¼ä¾æ¬¡è¾åºç顺åºå°±æ¯å¾çæææåº
**è¦æ±ï¼æåå¾ä¸å
¶ä¸æ²¡æç¯**
**åºç¨ï¼äºä»¶å®æï¼ç¼è¯é¡ºåº**
> 卿们ç项ç®ä¸ï¼é¡¹ç®ä¹é´äºç¸ä¾èµï¼å°±æ¯æææåºçä¸ä¸ªåºç¨ï¼ä»æåºå±ä¾èµçå
å¾ä¸å±ç¼è¯ï¼æç»ææ»ç项ç®ç¼è¯éè¿ãæä»¥é¡¹ç®ä¸å¾ªç¯ä¾èµæ¯ç¼è¯ä¸éè¿ç
ä¾å¦ä¸åçæåæ ç¯å¾ï¼
```
graph LR;
A-->B
B-->C
A-->C
C-->E
E-->F
C-->T
F-->T
```
å¾ä¸çåæ¯ä»£è¡¨äºæ
ï¼åäºæ
çå
å顺åºå°±æ¯æç
§æåå¾çæè¿°ï¼è¯·å®æäºæ
çå
å顺åºï¼æææåºï¼ã
æææåºä¸ºï¼A B C E F T
```Java
package class10;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class Code03_TopologySort {
// æåæ ç¯å¾ï¼è¿åæææåºç顺åºlist
public static List sortedTopology(Graph graph) {
// keyï¼æä¸ä¸ªnode
// valueï¼è¯¥èç¹å©ä½çå
¥åº¦
HashMap inMap = new HashMap<>();
// å©ä½å
¥åº¦ä¸º0çç¹ï¼æè½è¿è¿ä¸ªéå
Queue zeroInQueue = new LinkedList<>();
// æ¿å°è¯¥å¾ä¸ææçç¹é
for (Node node : graph.nodes.values()) {
// åå§åæ¯ä¸ªç¹ï¼æ¯ä¸ªç¹çå
¥åº¦æ¯åå§èç¹çå
¥åº¦ä¿¡æ¯
// å å
¥inMap
inMap.put(node, node.in);
// ç±äºæ¯æåæ ç¯å¾ï¼åå¿
宿å
¥åº¦ä¸º0çèµ·å§ç¹ãæ¾å
¥å°zeroInQueue
if (node.in == 0) {
zeroInQueue.add(node);
}
}
// æææåºçç»æï¼ä¾æ¬¡å å
¥result
List result = new ArrayList<>();
while (!zeroInQueue.isEmpty()) {
// 该æåæ ç¯å¾åå§å
¥åº¦ä¸º0çç¹ï¼ç´æ¥å¼¹åºæ¾å
¥ç»æéä¸
Node cur = zeroInQueue.poll();
result.add(cur);
// 该èç¹çä¸ä¸å±é»å±
èç¹ï¼å
¥åº¦åä¸ä¸å å
¥å°å
¥åº¦çmapä¸
for (Node next : cur.nexts) {
inMap.put(next, inMap.get(next) - 1);
// 妿ä¸ä¸å±åå¨å
¥åº¦å为0çèç¹ï¼å å
¥å°0å
¥åº¦çéåä¸
if (inMap.get(next) == 0) {
zeroInQueue.add(next);
}
}
}
return result;
}
}
```
1.2.5 å¾çæå°çææ ç®æ³
> æå°çææ è§£éï¼å°±æ¯å¨ä¸ç ´ååæå¾ç¹ä¸ç¹çè¿éæ§åºç¡ä¸ï¼è®©è¿éçè¾¹çæ´ä½æå¼æå°ãè¿åæå°æå¼æè
è¾¹çéå
1.2.5.1 Kruskalï¼å
鲿¯å¡å°ï¼ç®æ³
> è¿éæ§åå©å¹¶æ¥éå®ç°
1ãæ»æ¯ä»æå¼æå°çè¾¹å¼å§èèï¼ä¾æ¬¡è坿å¼ä¾æ¬¡å大çè¾¹
2ãå½åçè¾¹è¦ä¹è¿å
¥æå°çææ çéåï¼è¦ä¹ä¸¢å¼
3ã妿å½åçè¾¹è¿å
¥æå°çææ çéåä¸ä¸ä¼å½¢æç¯ï¼å°±è¦å½åè¾¹
4ã妿å½åçè¾¹è¿å
¥æå°çææ çéåä¸ä¼å½¢æç¯ï¼å°±ä¸è¦å½åè¾¹
5ãèå¯å®ææè¾¹ä¹åï¼æå°çææ çéåä¹å°±å¾å°äº
```Java
package class10;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.Stack;
//undirected graph only
public class Code04_Kruskal {
// Union-Find Set æä»¬çå¹¶æ¥éç»æ
public static class UnionFind {
// key æä¸ä¸ªèç¹ï¼ value keyèç¹å¾ä¸çèç¹
private HashMap fatherMap;
// key æä¸ä¸ªéåç代表èç¹, value keyæå¨éåçèç¹ä¸ªæ°
private HashMap sizeMap;
public UnionFind() {
fatherMap = new HashMap();
sizeMap = new HashMap();
}
public void makeSets(Collection nodes) {
fatherMap.clear();
sizeMap.clear();
for (Node node : nodes) {
fatherMap.put(node, node);
sizeMap.put(node, 1);
}
}
private Node findFather(Node n) {
Stack path = new Stack<>();
while(n != fatherMap.get(n)) {
path.add(n);
n = fatherMap.get(n);
}
while(!path.isEmpty()) {
fatherMap.put(path.pop(), n);
}
return n;
}
public boolean isSameSet(Node a, Node b) {
return findFather(a) == findFather(b);
}
public void union(Node a, Node b) {
if (a == null || b == null) {
return;
}
Node aDai = findFather(a);
Node bDai = findFather(b);
if (aDai != bDai) {
int aSetSize = sizeMap.get(aDai);
int bSetSize = sizeMap.get(bDai);
if (aSetSize <= bSetSize) {
fatherMap.put(aDai, bDai);
sizeMap.put(bDai, aSetSize + bSetSize);
sizeMap.remove(aDai);
} else {
fatherMap.put(bDai, aDai);
sizeMap.put(aDai, aSetSize + bSetSize);
sizeMap.remove(bDai);
}
}
}
}
public static class EdgeComparator implements Comparator {
@Override
public int compare(Edge o1, Edge o2) {
return o1.weight - o2.weight;
}
}
// Kç®æ³
public static Set kruskalMST(Graph graph) {
// å
æ¿å°å¹¶æ¥éç»æ
UnionFind unionFind = new UnionFind();
// 该å¾çææç¹å å
¥å°å¹¶æ¥éç»æ
unionFind.makeSets(graph.nodes.values());
// è¾¹æç
§æå¼ä»å°å°å¤§æåºï¼å å
¥å°å
PriorityQueue priorityQueue = new PriorityQueue<>(new EdgeComparator());
for (Edge edge : graph.edges) { // M æ¡è¾¹
priorityQueue.add(edge); // O(logM)
}
Set result = new HashSet<>();
// å ä¸ä¸ºç©ºï¼å¼¹åºå°æ ¹å çå é¡¶
while (!priorityQueue.isEmpty()) {
// å设Mæ¡è¾¹ï¼O(logM)
Edge edge = priorityQueue.poll();
// å¦æè¯¥è¾¹çå·¦å³ä¸¤ä¾§ä¸å¨åä¸ä¸ªéåä¸
if (!unionFind.isSameSet(edge.from, edge.to)) { // O(1)
// è¦è¿æ¡è¾¹
result.add(edge);
// èåfromåto
unionFind.union(edge.from, edge.to);
}
}
return result;
}
}
```
> Kç®æ³æ±æ åå¾çæå°çææ ï¼æ±æå¼æ¯æ²¡é®é¢çï¼å¦æçº ç»æå°çææ çè¿éç»æï¼å®è´¨æ¯å°äºä¸ä¾§ï¼å³AæåB, BæåAåªä¼ä¿çå
¶ä¸ãå¯ä»¥æå¨è¡¥é½
1.2.5.2 Primç®æ³
> Pç®æ³æ éå¹¶æ¥éç»æï¼æ®ésetå³å¯æ»¡è¶³
1ãä»»ææå®ä¸ä¸ªåºåç¹ï¼è¬å¦A, Açç´æ¥è¾¹è¢«è§£é
2ãå¨Aè§£éçè¾¹ééæ©ä¸ä¸ªæå°çè¾¹ï¼è¯¥è¾¹ä¸¤ä¾§ææ²¡ææ°èç¹ï¼å¦ææéæ©è¯¥è¾¹ã没æå°±èå¼è¯¥è¾¹
3ãå¨è¢«éæ©çæ°èç¹ä¸åè§£é该èç¹çç´æ¥è¾¹
4ãå¨èå¤å§ï¼ç´å°ææç¹è¢«è§£é
```Java
package class10;
import java.util.Comparator;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Set;
// undirected graph only
public class Code05_Prim {
public static class EdgeComparator implements Comparator {
@Override
public int compare(Edge o1, Edge o2) {
return o1.weight - o2.weight;
}
}
public static Set primMST(Graph graph) {
// è§£éçè¾¹è¿å
¥å°æ ¹å
PriorityQueue priorityQueue = new PriorityQueue<>(new EdgeComparator());
// åªäºç¹è¢«è§£éåºæ¥äº
HashSet nodeSet = new HashSet<>();
// å·²ç»èèè¿çè¾¹ï¼ä¸è¦éå¤èè
Set result = new HashSet<>();
// 便¬¡æéççè¾¹å¨resulté
Set result = new HashSet<>();
// é便æäºä¸ä¸ªç¹,è¿å
¥å¾ªç¯å¤çå®åç´æ¥break
for (Node node : graph.nodes.values()) {
// node æ¯å¼å§ç¹
if (!nodeSet.contains(node)) {
// å¼å§èç¹ä¿ç
nodeSet.add(node);
// å¼å§èç¹çææé»å±
èç¹å
¨é¨æ¾å°å°æ ¹å
// å³ç±ä¸ä¸ªç¹ï¼è§£éææç¸è¿çè¾¹
for (Edge edge : node.edges) {
if (!edgeSet.contains(edge)) {
edgeSet.add(edge);
priorityQueue.add(edge);
}
}
while (!priorityQueue.isEmpty()) {
// å¼¹åºè§£éçè¾¹ä¸ï¼æå°çè¾¹
Edge edge = priorityQueue.poll();
// å¯è½çä¸ä¸ªæ°çç¹,fromå·²ç»è¢«èèäºï¼åªéè¦çto
Node toNode = edge.to;
// ä¸å«æçæ¶åï¼å°±æ¯æ°çç¹
if (!nodeSet.contains(toNode)) {
nodeSet.add(toNode);
result.add(edge);
for (Edge nextEdge : toNode.edges) {
// 没å è¿çï¼æ¾å
¥å°æ ¹å
if (!edgeSet.contains(edge)) {
edgeSet.add(edge);
priorityQueue.add(edge);
}
}
}
}
}
// ç´æ¥breakæå³çæä»¬ä¸ç¨èèæ£®æçæ
åµ
// 妿ä¸å breakæä»¬å¯ä»¥å
¼å®¹å¤ä¸ªæ åå¾ç森æççææ
// break;
}
return result;
}
// 请ä¿è¯graphæ¯è¿éå¾
// graph[i][j]表示ç¹iå°ç¹jçè·ç¦»ï¼å¦ææ¯ç³»ç»æå¤§å¼ä»£è¡¨æ è·¯
// è¿å弿¯æå°è¿éå¾çè·¯å¾ä¹å
public static int prim(int[][] graph) {
int size = graph.length;
int[] distances = new int[size];
boolean[] visit = new boolean[size];
visit[0] = true;
for (int i = 0; i < size; i++) {
distances[i] = graph[0][i];
}
int sum = 0;
for (int i = 1; i < size; i++) {
int minPath = Integer.MAX_VALUE;
int minIndex = -1;
for (int j = 0; j < size; j++) {
if (!visit[j] && distances[j] < minPath) {
minPath = distances[j];
minIndex = j;
}
}
if (minIndex == -1) {
return sum;
}
visit[minIndex] = true;
sum += minPath;
for (int j = 0; j < size; j++) {
if (!visit[j] && distances[j] > graph[minIndex][j]) {
distances[j] = graph[minIndex][j];
}
}
}
return sum;
}
public static void main(String[] args) {
System.out.println("hello world!");
}
}
```
1.2.6 å¾çæçè·¯å¾ç®æ³
1.2.6.1 Dijkstra(迪æ°ç¹æ¯æ)ç®æ³
> Dijkstraç®æ³å¿
é¡»è¦æ±è¾¹çæå¼ä¸ä¸ºè´ï¼ä¸å¿
é¡»æå®åºåç¹ãåå¯ä»¥æ±åºåç¹å°ææèç¹çæçè·ç¦»æ¯å¤å°ã妿å°è¾¾ä¸äºï¼ä¸ºæ£æ ç©·
1ãDijkstraç®æ³å¿
é¡»æå®ä¸ä¸ªæºç¹
2ãçæä¸ä¸ªæºç¹å°å个ç¹çæå°è·ç¦»è¡¨ï¼ä¸å¼å§åªæä¸æ¡è®°å½ï¼å³åç¹å°èªå·±çæå°è·ç¦»ä¸º0ï¼æºç¹å°å
¶ä»ææç¹çæå°è·ç¦»é½æªæ£æ 穷大
3ãä»è·ç¦»è¡¨ä¸æ¿åºæ²¡æ¿è¿è®°å½éçæå°è®°å½ï¼éè¿è¿ä¸ªç¹åºåçè¾¹ï¼æ´æ°æºç¹å°å个ç¹çæå°è·ç¦»è¡¨ï¼ä¸æéå¤è¿ä¸æ¥
4ãæºç¹å°ææçç¹è®°å½å¦æé½è¢«æ¿è¿ä¸éï¼è¿ç¨åæ¢ï¼æå°è·ç¦»è¡¨å¾å°äº
```Java
package class10;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
// 没æ¹è¿ä¹åççæ¬
public class Code06_Dijkstra {
// è¿åçmap表就æ¯ä»fromå°è¡¨ä¸keyçå个çæå°è·ç¦»
// æä¸ªç¹ä¸å¨mapä¸è®°å½ï¼åfromå°è¯¥ç¹ä½æ£æ ç©·
public static HashMap dijkstra1(Node from) {
// ä»fromåºåå°ææç¹çæå°è·ç¦»è¡¨
HashMap distanceMap = new HashMap<>();
// fromå°fromè·ç¦»ä¸º0
distanceMap.put(from, 0);
// å·²ç»æ±è¿è·ç¦»çèç¹ï¼åå¨selectedNodesä¸ï¼ä»¥ååä¹ä¸ç¢°
HashSet selectedNodes = new HashSet<>();
// from 0 å¾å°æ²¡éæ©è¿çç¹çæå°è·ç¦»
Node minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes);
// å¾å°minNodeä¹å
while (minNode != null) {
// æminNode对åºçè·ç¦»ååº,æ¤æ¶minNodeå°±æ¯æ¡¥è¿ç¹
int distance = distanceMap.get(minNode);
// æminNode䏿æçé»è¾¹æ¿åºæ¥
// è¿éå°±æ¯è¦æ¿å°ä¾å¦Aå°CåAå°æ¡¥è¿ç¹Båå°Cåªä¸ªè·ç¦»å°çè·ç¦»
for (Edge edge : minNode.edges) {
// ææ¡è¾¹å¯¹åºçä¸ä¸è·³èç¹toNode
Node toNode = edge.to;
// 妿å
³äºfromçdistencMap䏿²¡æå»toNodeçè®°å½ï¼è¡¨ç¤ºæ£æ ç©·ï¼ç´æ¥æ·»å 该æ¡
if (!distanceMap.containsKey(toNode)) {
// fromå°minNodeçè·ç¦»å ä¸ä¸ªminNodeå°å½åtoèç¹çè¾¹è·ç¦»
distanceMap.put(toNode, distance + edge.weight);
// 妿æï¼ç该è·ç¦»æ¯å¦æ´å°ï¼æ´å°å°±æ´æ°
} else {
distanceMap.put(edge.to,
Math.min(distanceMap.get(toNode), distance + edge.weight));
}
}
// éä¸minNodeï¼è¡¨ç¤ºfroméè¿minNodeå°å
¶ä»èç¹çæå°å¼å·²ç»æ¾å°
// minNodeå°ä¸å使ç¨
selectedNodes.add(minNode);
// å卿²¡æéæ©çèç¹ä¸æéMinNode彿fromçæ¡¥æ¥ç¹
minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes);
}
// æç»distanceMapå
¨é¨æ´æ°ï¼è¿å
return distanceMap;
}
// å¾å°æ²¡éæ©è¿çç¹çæå°è·ç¦»
public static Node getMinDistanceAndUnselectedNode(
HashMap distanceMap,
HashSet touchedNodes) {
Node minNode = null;
int minDistance = Integer.MAX_VALUE;
for (Entry entry : distanceMap.entrySet()) {
Node node = entry.getKey();
int distance = entry.getValue();
// 没æè¢«éæ©è¿ï¼ä¸è·ç¦»æå°
if (!touchedNodes.contains(node) && distance < minDistance) {
minNode = node;
minDistance = distance;
}
}
return minNode;
}
/**
* æä»¬å¯ä»¥åå©å°æ ¹å æ¥æ¿ä»£ä¹åçdistanceMapãè¾¾å°ä¼åç®æ³çç®ç
* åå æ¯ä¹åæä»¬è¦éåhash表éåºæå°è·ç¦»ï¼ç°å¨ç´æ¥æ¯å é¡¶å
ç´
* 使¯æä»¬æ¾å°éè¿æ¡¥èç¹æ´å°çè·ç¦»åï¼éè¦ä¸´æ¶æ´è¯¥å ç»æä¸å
ç´ æ°æ®
* æä»¥ç³»ç»æä¾çå æä»¬éè¦æ¹å
**/
public static class NodeRecord {
public Node node;
public int distance;
public NodeRecord(Node node, int distance) {
this.node = node;
this.distance = distance;
}
}
// èªå®ä¹å°æ ¹å ç»æ
// éè¦æä¾addå
ç´ çæ¹æ³ï¼åupdateå
ç´ çæ¹æ³
// éè¦æä¾ignoreæ¹æ³ï¼è¡¨ç¤ºæä»¬å·²ç»æ¾å°fromå°æèç¹çæçè·¯å¾
// ååºç°fromå°è¯¥èç¹çå
¶ä»è·¯å¾è·ç¦»ï¼æä»¬ç´æ¥å¿½ç¥
public static class NodeHeap {
private Node[] nodes; // å®é
çå ç»æ
// key æä¸ä¸ªnodeï¼ value ä¸é¢å ä¸çä½ç½®
// 妿èç¹æ¾ç»è¿è¿å ï¼ç°å¨ä¸å¨å ä¸ï¼ånode对åº-1
// ç¨æ¥æ¾éè¦ignoreçèç¹
private HashMap heapIndexMap;
// key æä¸ä¸ªèç¹ï¼ value 仿ºèç¹åºåå°è¯¥èç¹çç®åæå°è·ç¦»
private HashMap distanceMap;
private int size; // å 䏿å¤å°ä¸ªç¹
public NodeHeap(int size) {
nodes = new Node[size];
heapIndexMap = new HashMap<>();
distanceMap = new HashMap<>();
size = 0;
}
// è¯¥å æ¯å¦ç©º
public boolean isEmpty() {
return size == 0;
}
// æä¸ä¸ªç¹å«nodeï¼ç°å¨åç°äºä¸ä¸ªä»æºèç¹åºåå°è¾¾nodeçè·ç¦»ä¸ºdistance
// 夿è¦ä¸è¦æ´æ°ï¼å¦æéè¦çè¯ï¼å°±æ´æ°
public void addOrUpdateOrIgnore(Node node, int distance) {
// å¦æè¯¥èç¹å¨å ä¸ï¼å°±çæ¯å¦éè¦æ´æ°
if (inHeap(node)) {
distanceMap.put(node, Math.min(distanceMap.get(node), distance));
// 该èç¹è¿å ï¼å¤ææ¯å¦éè¦è°æ´
insertHeapify(node, heapIndexMap.get(node));
}
// å¦ææ²¡æè¿å
¥è¿å ãæ°å»ºï¼è¿å
if (!isEntered(node)) {
nodes[size] = node;
heapIndexMap.put(node, size);
distanceMap.put(node, distance);
insertHeapify(node, size++);
}
// 妿ä¸å¨å ä¸ï¼ä¸è¿æ¥è¿å ä¸ï¼ä»ä¹ä¹ä¸åï¼ignore
}
// å¼¹åºfromå°å é¡¶èç¹çå
ç´ ï¼è·åå°è¯¥å
ç´ çæå°è·ç¦»ï¼åè°æ´å ç»æ
public NodeRecord pop() {
NodeRecord nodeRecord = new NodeRecord(nodes[0], distanceMap.get(nodes[0]));
// ææåä¸ä¸ªå
ç´ æ¾å¨å é¡¶ï¼è¿è¡heapify
swap(0, size - 1);
heapIndexMap.put(nodes[size - 1], -1);
distanceMap.remove(nodes[size - 1]);
// free C++åå¦è¿è¦æåæ¬å é¡¶èç¹ææï¼å¯¹javaåå¦ä¸å¿
nodes[size - 1] = null;
heapify(0, --size);
return nodeRecord;
}
private void insertHeapify(Node node, int index) {
while (distanceMap.get(nodes[index])
< distanceMap.get(nodes[(index - 1) / 2])) {
swap(index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
private void heapify(int index, int size) {
int left = index * 2 + 1;
while (left < size) {
int smallest = left + 1 < size && distanceMap.get(nodes[left + 1]) < distanceMap.get(nodes[left])
? left + 1
: left;
smallest = distanceMap.get(nodes[smallest])
< distanceMap.get(nodes[index]) ? smallest : index;
if (smallest == index) {
break;
}
swap(smallest, index);
index = smallest;
left = index * 2 + 1;
}
}
// 夿nodeæ¯å¦è¿æ¥è¿å
private boolean isEntered(Node node) {
return heapIndexMap.containsKey(node);
}
// 夿æä¸ªèç¹æ¯å¦å¨å ä¸
private boolean inHeap(Node node) {
return isEntered(node) && heapIndexMap.get(node) != -1;
}
private void swap(int index1, int index2) {
heapIndexMap.put(nodes[index1], index2);
heapIndexMap.put(nodes[index2], index1);
Node tmp = nodes[index1];
nodes[index1] = nodes[index2];
nodes[index2] = tmp;
}
}
// 使ç¨èªå®ä¹å°æ ¹å ï¼æ¹è¿åçdijkstraç®æ³
// ä»fromåºåï¼ææfromè½å°è¾¾çèç¹ï¼çæå°è¾¾æ¯ä¸ªèç¹çæå°è·¯å¾è®°å½å¹¶è¿å
public static HashMap dijkstra2(Node from, int size) {
// ç³è¯·å
NodeHeap nodeHeap = new NodeHeap(size);
// å¨å 䏿·»å fromèç¹å°fromèç¹è·ç¦»ä¸º0
nodeHeap.addOrUpdateOrIgnore(from, 0);
// æç»çç»æé
HashMap result = new HashMap<>();
while (!nodeHeap.isEmpty()) {
// æ¯æ¬¡å¨å°æ ¹å å¼¹åºå é¡¶å
ç´
NodeRecord record = nodeHeap.pop();
// æ¿åºçèç¹
Node cur = record.node;
// fromå°è¯¥èç¹çè·ç¦»
int distance = record.distance;
// 以æ¤ä¸ºæ¡¥æ¥ç¹ï¼æ¾æ¯å¦ææ´å°çè·ç¦»å°è¯¥èç¹çå
¶ä»toèç¹
// addOrUpdateOrIgnoreè¯¥æ¹æ³ä¿è¯å¦æfromå°toçèç¹æ²¡æï¼å°±add
// 妿æ,çæ¯å¦éè¦Ignoreï¼å¦æä¸éè¦Ignore䏿´å°ï¼å°±Update
for (Edge edge : cur.edges) {
nodeHeap.addOrUpdateOrIgnore(edge.to, edge.weight + distance);
}
result.put(cur, distance);
}
return result;
}
}
```
1.2.6.2 floydç®æ³
> å¾èç¹çæçè·¯å¾ï¼å¤çæå¼å¯è½ä¸ºè´çæ
åµãä¸å±for循ç¯ï¼æ¯è¾ç®å