

모든 정점(Node)이 사이클 없이 최소 비용으로 연결되어있는 트리입니다.
신장트리
신장: 늘리다, 뻗어나가다 라는 뜻
모든 정점(Node)이 사이클 없이 연결된 트리를 뜻합니다.

간선(Edge)을 가중치(Weight) 기준으로 정렬한 뒤에
가장 낮은 가중치부터 트리에 추가하면서,
사이클을 만들지 않으면 트리에 추가하는 알고리즘입니다.




public Tree kruskal(List<Edge> graph){
Tree tree = new Tree();
graph = sortByWeightAsc(graph); // 간선(edge)의 가중치(weight)를 기준으로 오름차순 정렬
for (Edge edge: graph){
// MST의 Edge 개수 == (그래프의 Node 개수 - 1) 이면 반복문 종료
if(graph.getNodeSize() == (tree.getEdgeSize() - 1)){
break;
}
// 사이클이 생기면 다음 간선으로
if(tree.detectCycle(edge){
continue;
}
// 사이클이 아니면 간선(Edge) 추가
tree.add(edge);
}
return tree;
}
시작할 정점을 정하고 인접한 간선들 중에 가중치가 적은 간선들을 트리에 추가하는 알고리즘입니다. 마찬가지로 사이클이 존재해선 안됩니다.




public Tree prim(List<Edge> graph, Node startNode){
Tree tree = new Tree();
tree.setStart(startNode); // 시작하는 정점(Node) 설정
// 그래프의 Node 개수 == (트리의 Edge 개수 - 1)이면 반복문 종료
for(int i = 0; i < graph.getNodeSize() - 1; i++){
// 사이클이 생기면 다음 간선으로
if(tree.detectCycle(edge){
continue;
}
// 트리와 인접한 모든 간선(Edge) 중에 가중치(Weight)가 가장 낮은 간선 하나를 찾아 추가
Edge edge = findSmallestEdge(tree, graph);
tree.add(edge);
}
return tree;
}
cost: 각 정점(Node)들의 최소 비용을 저장하고 있는 우선순위 큐
visit: 앞으로 방문해야 할 정점(Node)들을 저장하고 있는 객체




public Map<Node, Long> djikstra(Graph graph, Node startNode){
final long INF = Long.MAX_VALUE / 4;
Map<Node,Long> cost = new HashMap<>();
// 1. 출발 정점(Node)의 비용(cost)은 0, 나머지는 무한대/큰 값(∞)로 초기화합니다.
for(Node node: graph.getNodes()){
cost.put(node, INF);
}
cost.put(startNode, 0);
// 2-1. 시작 정점(Node)을 방문하지 않은 곳(visit)에 저장합니다.
PriorityQueue<Node> visit = new PriorityQueue<>();
visit.add(startNode);
// 2-2. 이미 방문한 정점(Node)들을 저장하는 객체를 생성합니다.
List<Node> visited = new ArrayList<>();
while(!visit.isEmpty()){
// 3. 방문하지 않은 정점(Node)들 중, 비용이 가장 적은 정점(Node)을 현재정점(currentNode)으로 설정
Node currentNode = visit.poll();
visited.add(currentNode);
// 4-1. 현재정점(currentNode)과 인접한 정점(Node)들을 확인합니다.
for (Node neighborNode: currentNode.getNeighbors()){
// 4-2. 방문했던 정점(Node)이면, 스킵합니다.
if(visited.contains(neighborNode)) continue;
// 4-3. cost에 저장된 비용과 비교하여 최소비용을 갱신합니다.
Long tmpCost = currentNode.getCost() + currentNode.calCost(neighborNode);
if(cost.get(neighborNode) > tmpCost){
cost.put(neighborNode, tmpCost);
}
// 4-4. 방문하지 않았다면 방문해야 할 정점(visit)에 저장합니다.
visit.add(neighborNode);
}
}
return cost;
}