diff --git a/algorithms-miscellaneous-5/pom.xml b/algorithms-miscellaneous-5/pom.xml
index f2db71a6da..4131e1791d 100644
--- a/algorithms-miscellaneous-5/pom.xml
+++ b/algorithms-miscellaneous-5/pom.xml
@@ -41,11 +41,6 @@
guava
${guava.version}
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
org.junit.platform
junit-platform-commons
@@ -78,7 +73,6 @@
1.11
3.6.1
28.1-jre
- 2.10.2
1.6.0
diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/BoruvkaMST.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/BoruvkaMST.java
deleted file mode 100644
index 0f8bc5b296..0000000000
--- a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/BoruvkaMST.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.baeldung.algorithms.boruvka;
-
-public class BoruvkaMST {
-
- private static Tree mst = new Tree();
- private static int totalWeight;
-
- public BoruvkaMST(Graph graph) {
- DisjointSet dSet = new DisjointSet(graph.getNodes());
-
- // repeat at most log N times or until we have N-1 edges
- for (int t = 1; t < graph.getNodes() && mst.getEdgeCount() < graph.getNodes() - 1; t = t + t) {
-
- // foreach tree in forest, find closest edge
- Edge[] closestEdgeArray = new Edge[graph.getNodes()];
- for (Edge edge : graph.getAllEdges()) {
- int first = edge.getFirst();
- int second = edge.getSecond();
- int firstParent = dSet.getParent(first);
- int secondParent = dSet.getParent(second);
- if (firstParent == secondParent) {
- continue; // same tree
- }
- if (closestEdgeArray[firstParent] == null || edge.getWeight() < closestEdgeArray[firstParent].getWeight()) {
- closestEdgeArray[firstParent] = edge;
- }
- if (closestEdgeArray[secondParent] == null || edge.getWeight() < closestEdgeArray[secondParent].getWeight()) {
- closestEdgeArray[secondParent] = edge;
- }
- }
-
- // add newly discovered edges to MST
- for (int i = 0; i < graph.getNodes(); i++) {
- Edge edge = closestEdgeArray[i];
- if (edge != null) {
- int first = edge.getFirst();
- int second = edge.getSecond();
- // don't add the same edge twice
- if (dSet.getParent(first) != dSet.getParent(second)) {
- mst.addEdge(edge);
- totalWeight += edge.getWeight();
- dSet.union(first, second);
- }
- }
- }
- }
- }
-
- public Iterable getMST() {
- return mst;
- }
-
- public int getTotalWeight() {
- return totalWeight;
- }
-
- public String toString() {
- return "MST: " + mst.toString() + " | Total Weight: " + totalWeight;
- }
-
-}
diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/DisjointSet.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/DisjointSet.java
deleted file mode 100644
index 7769686e36..0000000000
--- a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/DisjointSet.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.baeldung.algorithms.boruvka;
-
-import java.util.Arrays;
-
-public class DisjointSet {
-
- private int[] nodeParents;
- private int[] nodeRanks;
-
- public DisjointSet(int n) {
- nodeParents = new int[n];
- nodeRanks = new int[n];
- for (int i = 0; i < n; i++) {
- nodeParents[i] = i;
- nodeRanks[i] = 0;
- }
- }
-
- public int getParent(int node) {
- while (node != nodeParents[node]) {
- node = nodeParents[node];
- }
- return node;
- }
-
- public void union(int node1, int node2) {
- int node1Parent = getParent(node1);
- int node2Parent = getParent(node2);
- if (node1Parent == node2Parent) {
- return;
- }
-
- if (nodeRanks[node1Parent] < nodeRanks[node2Parent]) {
- nodeParents[node1Parent] = node2Parent;
- }
- else if (nodeRanks[node1Parent] > nodeRanks[node2Parent]) {
- nodeParents[node2Parent] = node1Parent;
- }
- else {
- nodeParents[node2Parent] = node1Parent;
- nodeRanks[node1Parent]++;
- }
- }
-
- public String toString() {
- return "Parent: " + Arrays.toString(nodeParents) + "Rank: " + Arrays.toString(nodeRanks);
- }
-
-}
diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Edge.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Edge.java
deleted file mode 100644
index 6ee136fc48..0000000000
--- a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Edge.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.baeldung.algorithms.boruvka;
-
-public class Edge {
-
- private final int first;
- private final int second;
- private final int weight;
-
- public Edge(int first, int second, int weight) {
- this.first = first;
- this.second = second;
- this.weight = weight;
- }
-
- public double getWeight() {
- return weight;
- }
-
- public int getFirst() {
- return first;
- }
-
- public int getSecond() {
- return second;
- }
-
- public int getOtherNode(int firstNode) {
- int secondNode = 0;
- if (firstNode == first)
- secondNode = second;
- else if (firstNode == second)
- secondNode = first;
- return secondNode;
- }
-
- public String toString() {
- return String.format("%d-%d %d", first, second, weight);
- }
-
-}
diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Graph.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Graph.java
deleted file mode 100644
index e899007dfa..0000000000
--- a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Graph.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.baeldung.algorithms.boruvka;
-
-import java.io.IOException;
-
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.databind.JsonMappingException;
-
-public class Graph {
-
- private int nodes;
- private int edges;
- private Tree[] trees;
-
- public Graph(Input jsonGraph) throws JsonParseException, JsonMappingException, IOException {
- nodes = jsonGraph.getNodes();
- trees = (Tree[]) new Tree[nodes];
- for (int i = 0; i < nodes; i++) {
- trees[i] = new Tree();
- }
-
- int edgesFromInput = jsonGraph.getEdges();
- for (int i = 0; i < edgesFromInput; i++) {
- int first = jsonGraph.getEdgeList()
- .get(i)
- .getFirst();
- int second = jsonGraph.getEdgeList()
- .get(i)
- .getSecond();
- int weight = jsonGraph.getEdgeList()
- .get(i)
- .getWeight();
- Edge edge = new Edge(first, second, weight);
-
- trees[first].addEdge(edge);
- trees[second].addEdge(edge);
- edges++;
- }
-
- }
-
- public int getNodes() {
- return nodes;
- }
-
- public int getEdges() {
- return edges;
- }
-
- public Iterable iterableTree(int i) {
- return trees[i];
- }
-
- public Iterable getAllEdges() {
- Iterable list = new Tree();
- for (int i = 0; i < nodes; i++) {
- for (Edge edge : iterableTree(i)) {
- if (edge.getOtherNode(i) > i) {
- ((Tree) list).addEdge(edge);
- }
- }
- }
- return list;
- }
-}
diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Input.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Input.java
deleted file mode 100644
index b52720d5e9..0000000000
--- a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Input.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.baeldung.algorithms.boruvka;
-
-import java.util.List;
-
-public class Input {
- private int nodes;
- private int edges;
- private List edgeList;
-
- public int getNodes() {
- return nodes;
- }
-
- public void setNodes(int nodes) {
- this.nodes = nodes;
- }
-
- public int getEdges() {
- return edges;
- }
-
- public void setEdges(int edges) {
- this.edges = edges;
- }
-
- public List getEdgeList() {
- return edgeList;
- }
-
- public void setEdgeList(List edgeList) {
- this.edgeList = edgeList;
- }
-
- static class E {
- private int first;
- private int second;
- private int weight;
-
- public int getFirst() {
- return first;
- }
-
- public void setFirst(int first) {
- this.first = first;
- }
-
- public int getSecond() {
- return second;
- }
-
- public void setSecond(int second) {
- this.second = second;
- }
-
- public int getWeight() {
- return weight;
- }
-
- public void setWeight(int weight) {
- this.weight = weight;
- }
-
- }
-
-}
diff --git a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Tree.java b/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Tree.java
deleted file mode 100644
index cc28233e07..0000000000
--- a/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/boruvka/Tree.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.baeldung.algorithms.boruvka;
-
-import java.util.Iterator;
-
-public class Tree implements Iterable {
- private Node root;
- private int edgeCount;
-
- private static class Node {
- private Edge edge;
- private Node next;
-
- public String toString() {
- String nextStr = next != null ? next.toString() : "";
- return edge.toString() + " | " + nextStr;
- }
- }
-
- public Tree() {
- root = null;
- edgeCount = 0;
- }
-
- public int getEdgeCount() {
- return edgeCount;
- }
-
- public void addEdge(Edge edge) {
- Node oldRoot = root;
- root = new Node();
- root.edge = edge;
- root.next = oldRoot;
- edgeCount++;
- }
-
- public String toString() {
- String rootStr = root != null ? root.toString() : "";
- return "Tree: " + rootStr + "Size: " + edgeCount;
- }
-
- public Iterator iterator() {
- return new LinkedIterator(root);
- }
-
- private class LinkedIterator implements Iterator {
- private Node current;
-
- public LinkedIterator(Node root) {
- current = root;
- }
-
- public boolean hasNext() {
- return current != null;
- }
-
- public Edge next() {
- Edge edge = current.edge;
- current = current.next;
- return edge;
- }
- }
-
-}
diff --git a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/boruvka/BoruvkaUnitTest.java b/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/boruvka/BoruvkaUnitTest.java
deleted file mode 100644
index 1d03d2d4d9..0000000000
--- a/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/boruvka/BoruvkaUnitTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.baeldung.algorithms.boruvka;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-public class BoruvkaUnitTest {
-
- private Input input;
- private static String INPUT_JSON = "/input.json";
-
- @Before
- public void convertInputJsonToObject() throws JsonParseException, JsonMappingException, IOException {
- ObjectMapper mapper = new ObjectMapper();
- StringBuilder jsonStr = new StringBuilder();
- try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(BoruvkaMST.class.getResourceAsStream(INPUT_JSON)))) {
- String line;
- while ((line = bufferedReader.readLine()) != null) {
- jsonStr.append(line)
- .append("\n");
- }
- }
-
- input = mapper.readValue(jsonStr.toString(), Input.class);
-
- }
-
- @Test
- public void givenInputGraph_whenBoruvkaPerformed_thenMinimumSpanningTree() throws JsonParseException, JsonMappingException, IOException {
- Graph graph = new Graph(input);
- BoruvkaMST boruvkaMST = new BoruvkaMST(graph);
-
- Tree mst = (Tree) boruvkaMST.getMST();
-
- assertEquals(30, boruvkaMST.getTotalWeight());
- assertEquals(4, mst.getEdgeCount());
- }
-
-}
diff --git a/algorithms-miscellaneous-6/pom.xml b/algorithms-miscellaneous-6/pom.xml
index 5daa000ea3..fda9cf10f9 100644
--- a/algorithms-miscellaneous-6/pom.xml
+++ b/algorithms-miscellaneous-6/pom.xml
@@ -11,5 +11,17 @@
parent-modules
1.0.0-SNAPSHOT
+
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+
+
+ 28.1-jre
+
diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/BoruvkaMST.java b/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/BoruvkaMST.java
new file mode 100644
index 0000000000..7dae21648c
--- /dev/null
+++ b/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/BoruvkaMST.java
@@ -0,0 +1,84 @@
+package com.baeldung.algorithms.boruvka;
+
+import com.google.common.graph.EndpointPair;
+import com.google.common.graph.MutableValueGraph;
+import com.google.common.graph.ValueGraphBuilder;
+
+public class BoruvkaMST {
+
+ private static MutableValueGraph mst = ValueGraphBuilder.undirected()
+ .build();
+ private static int totalWeight;
+
+ public BoruvkaMST(MutableValueGraph graph) {
+
+ int size = graph.nodes().size();
+
+ UnionFind uf = new UnionFind(size);
+
+ // repeat at most log N times or until we have N-1 edges
+ for (int t = 1; t < size && mst.edges().size() < size - 1; t = t + t) {
+
+ EndpointPair[] closestEdgeArray = new EndpointPair[size];
+
+ // foreach tree in graph, find closest edge
+ for (EndpointPair edge : graph.edges()) {
+ int u = edge.nodeU();
+ int v = edge.nodeV();
+ int uParent = uf.find(u);
+ int vParent = uf.find(v);
+ if (uParent == vParent) {
+ continue; // same tree
+ }
+
+ int weight = graph.edgeValueOrDefault(u, v, 0);
+
+ if (closestEdgeArray[uParent] == null) {
+ closestEdgeArray[uParent] = edge;
+ }
+ if (closestEdgeArray[vParent] == null) {
+ closestEdgeArray[vParent] = edge;
+ }
+
+ int uParentWeight = graph.edgeValueOrDefault(closestEdgeArray[uParent].nodeU(), closestEdgeArray[uParent].nodeV(), 0);
+ int vParentWeight = graph.edgeValueOrDefault(closestEdgeArray[vParent].nodeU(), closestEdgeArray[vParent].nodeV(), 0);
+
+ if (weight < uParentWeight) {
+ closestEdgeArray[uParent] = edge;
+ }
+ if (weight < vParentWeight) {
+ closestEdgeArray[vParent] = edge;
+ }
+ }
+
+ // add newly discovered edges to MST
+ for (int i = 0; i < size; i++) {
+ EndpointPair edge = closestEdgeArray[i];
+ if (edge != null) {
+ int u = edge.nodeU();
+ int v = edge.nodeV();
+ int weight = graph.edgeValueOrDefault(u, v, 0);
+ // don't add the same edge twice
+ if (uf.find(u) != uf.find(v)) {
+ mst.putEdgeValue(u, v, weight);
+ totalWeight += weight;
+ uf.union(u, v);
+ }
+ }
+ }
+ }
+ }
+
+ public MutableValueGraph getMST() {
+ return mst;
+ }
+
+ public int getTotalWeight() {
+ return totalWeight;
+ }
+
+ public String toString() {
+ return "MST: " + mst.toString() + " | Total Weight: " + totalWeight;
+ }
+
+}
diff --git a/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/UnionFind.java b/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/UnionFind.java
new file mode 100644
index 0000000000..33c9c4a4c8
--- /dev/null
+++ b/algorithms-miscellaneous-6/src/main/java/com/baeldung/algorithms/boruvka/UnionFind.java
@@ -0,0 +1,39 @@
+package com.baeldung.algorithms.boruvka;
+
+public class UnionFind {
+ private int[] parents;
+ private int[] ranks;
+
+ public UnionFind(int n) {
+ parents = new int[n];
+ ranks = new int[n];
+ for (int i = 0; i < n; i++) {
+ parents[i] = i;
+ ranks[i] = 0;
+ }
+ }
+
+ public int find(int u) {
+ while (u != parents[u]) {
+ u = parents[u];
+ }
+ return u;
+ }
+
+ public void union(int u, int v) {
+ int uParent = find(u);
+ int vParent = find(v);
+ if (uParent == vParent) {
+ return;
+ }
+
+ if (ranks[uParent] < ranks[vParent]) {
+ parents[uParent] = vParent;
+ } else if (ranks[uParent] > ranks[vParent]) {
+ parents[vParent] = uParent;
+ } else {
+ parents[vParent] = uParent;
+ ranks[uParent]++;
+ }
+ }
+}
diff --git a/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/boruvka/BoruvkaUnitTest.java b/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/boruvka/BoruvkaUnitTest.java
new file mode 100644
index 0000000000..e61e1e668d
--- /dev/null
+++ b/algorithms-miscellaneous-6/src/test/java/com/baeldung/algorithms/boruvka/BoruvkaUnitTest.java
@@ -0,0 +1,37 @@
+package com.baeldung.algorithms.boruvka;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.graph.MutableValueGraph;
+import com.google.common.graph.ValueGraphBuilder;
+
+public class BoruvkaUnitTest {
+
+ private MutableValueGraph graph;
+
+ @Before
+ public void setup() {
+ graph = ValueGraphBuilder.undirected()
+ .build();
+ graph.putEdgeValue(0, 1, 8);
+ graph.putEdgeValue(0, 2, 5);
+ graph.putEdgeValue(1, 2, 9);
+ graph.putEdgeValue(1, 3, 11);
+ graph.putEdgeValue(2, 3, 15);
+ graph.putEdgeValue(2, 4, 10);
+ graph.putEdgeValue(3, 4, 7);
+ }
+
+ @Test
+ public void givenInputGraph_whenBoruvkaPerformed_thenMinimumSpanningTree() {
+ BoruvkaMST boruvkaMST = new BoruvkaMST(graph);
+ MutableValueGraph mst = boruvkaMST.getMST();
+
+ assertEquals(30, boruvkaMST.getTotalWeight());
+ assertEquals(4, mst.edges().size());
+ }
+
+}