图构造与相关算法
图的实现
import java. util. ArrayList;
public class Node {
public int value;
public int in;
public int out;
public ArrayList< Node> nexts;
public ArrayList< Edge> edges;
public Node ( int value) {
this . value = value;
in = 0 ;
out = 0 ;
nexts = new ArrayList < > ( ) ;
edges = new ArrayList < > ( ) ;
}
}
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;
}
}
import java. util. HashMap;
import java. util. HashSet;
public class Graph {
public HashMap< Integer, Node> nodes;
public HashSet< Edge> edges;
public Graph ( ) {
nodes = new HashMap < > ( ) ;
edges = new HashSet < > ( ) ;
}
}
图的遍历
import java. util. HashSet;
import java. util. Stack;
public class Dfs {
public static void bfs ( Node node) {
if ( node == null) {
return ;
}
Stack< Node> stack = new Stack < > ( ) ;
HashSet< Node> 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 ;
}
}
}
}
}
import java. util. HashSet;
import java. util. LinkedList;
import java. util. Queue;
public class Bfs {
public static void bfs ( Node node) {
if ( node == null) {
return ;
}
Queue< Node> queue = new LinkedList < > ( ) ;
HashSet< Node> 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) {
if ( ! set. contains ( next) ) {
set. add ( next) ;
queue. add ( next) ;
}
}
}
}
}
图的拓扑排序
import java. util. ArrayList;
import java. util. HashMap;
import java. util. LinkedList;
import java. util. List;
import java. util. Queue;
public class SortedTopology {
public static List< Node> sortedTopology ( Graph graph) {
HashMap< Node, Integer> inMap = new HashMap < > ( ) ;
Queue< Node> zeroInQueue = new LinkedList < > ( ) ;
for ( Node node: graph. nodes. values ( ) ) {
inMap. put ( node, node. in) ;
if ( node. in== 0 ) {
zeroInQueue. add ( node) ;
}
}
List< Node> result = new ArrayList < > ( ) ;
while ( ! zeroInQueue. isEmpty ( ) ) {
Node cur = zeroInQueue. poll ( ) ;
result. add ( cur) ;
for ( Node next: cur. nexts) {
inMap. put ( next, inMap. get ( next) - 1 ) ;
if ( inMap. get ( next) == 0 ) {
zeroInQueue. add ( next) ;
}
}
}
return result;
}
}
图的最小生成树
import java. util. Comparator;
import java. util. HashSet;
import java. util. PriorityQueue;
import java. util. Set;
public class Prim {
public static class EdgeComparator implements Comparator < Edge> {
public int compare ( Edge e1, Edge e2) {
return e1. weight - e2. weight;
}
}
public static Set< Edge> PrimMST ( Graph graph) {
PriorityQueue< Edge> priorityQueue = new PriorityQueue < > ( new EdgeComparator ( ) ) ;
HashSet< Node> nodeSet = new HashSet < > ( ) ;
HashSet< Edge> edgeSet = new HashSet < > ( ) ;
Set< Edge> result = new HashSet < > ( ) ;
for ( Node node : graph. nodes. values ( ) ) {
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 ( ) ;
Node toNode = edge. to;
if ( ! nodeSet. contains ( toNode) ) {
nodeSet. add ( toNode) ;
result. add ( edge) ;
for ( Edge nextEdge : toNode. edges)
if ( ! edgeSet. contains ( nextEdge) ) {
edgeSet. add ( nextEdge) ;
priorityQueue. add ( nextEdge) ;
}
}
}
}
}
return result;
}
}
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;
public class UnionFindAndKruskal {
public static class UnionFind {
private HashMap< Node, Node> fatherMap;
private HashMap< Node, Integer> sizeMap;
public UnionFind ( ) {
fatherMap = new HashMap < Node, Node> ( ) ;
sizeMap = new HashMap < Node, Integer> ( ) ;
}
public void makeSets ( Collection< Node> nodes) {
fatherMap. clear ( ) ;
sizeMap. clear ( ) ;
for ( Node node: nodes) {
fatherMap. put ( node, node) ;
sizeMap. put ( node, 1 ) ;
}
}
private Node findFather ( Node n) {
Stack< Node> 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 < Edge> {
@Override
public int compare ( Edge o1, Edge o2) {
return o1. weight- o2. weight;
}
}
public static Set< Edge> kruskalMST ( Graph graph) {
UnionFind unionFind = new UnionFind ( ) ;
unionFind. makeSets ( graph. nodes. values ( ) ) ;
PriorityQueue< Edge> priorityQueue = new PriorityQueue < > ( new EdgeComparator ( ) ) ;
for ( Edge edge: graph. edges) {
priorityQueue. add ( edge) ;
}
Set< Edge> result = new HashSet < > ( ) ;
while ( ! priorityQueue. isEmpty ( ) ) {
Edge edge = priorityQueue. poll ( ) ;
if ( ! unionFind. isSameSet ( edge. from, edge. to) ) {
result. add ( edge) ;
unionFind. union ( edge. from, edge. to) ;
}
}
return result;
}
}