snippetjavaModerate
Topological sort in Java
Viewed 0 times
sorttopologicaljava
Problem
I am learning algorithms in graphs. I have implemented topological sort using Java. Kindly review my code and provide me with feedback.
```
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class TopologicalSortGraph {
/**
* This Topological Sort implementation takes the example graph in
* Version 1: implementation with unweighted
* Assumption : Graph is directed
*/
TopologicalSortGraph Graph = new TopologicalSortGraph();
//public LinkedList nodes = new LinkedList();
public static void topologicalSort(Graph graph) {
Queue q = new LinkedList();
int vertexProcessesCtr = 0;
for(Node m : graph.nodes){
if(m.inDegree==0){
++vertexProcessesCtr;
q.add(m);
System.out.println(m.data);
}
}
while(!q.isEmpty()) {
Node m = q.poll();
//System.out.println(m.data);
for(Node child : m.AdjacenctNode){
--child.inDegree;
if(child.inDegree==0){
q.add(child);
++vertexProcessesCtr;
System.out.println(child.data);
}
}
}
if(vertexProcessesCtr > graph.vertices) {
System.out.println();
}
}
public static void main(String[] args) {
Graph g= new Graph();
g.vertices=8;
Node TEN = new Node("10");
Node ELEVEN = new Node("11");
Node TWO = new Node("2");
Node THREE = new Node("3");
Node FIVE = new Node("5");
Node SEVEN = new Node("7");
Node EIGHT = new Node("8");
Node NINE = new Node("9");
SEVEN.AdjacenctNode.add(ELEVEN);
ELEVEN.inDegree++;
SEVEN.AdjacenctNode.add(EIGHT);
EIGHT.inDegree++;
FIVE.AdjacenctNode.add(ELEVEN);
ELEVEN.inDegree++;
THREE.AdjacenctNode.add(EIGHT);
EIGHT.inDegree++;
THREE.AdjacenctNode.add(TEN);
TEN
```
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class TopologicalSortGraph {
/**
* This Topological Sort implementation takes the example graph in
* Version 1: implementation with unweighted
* Assumption : Graph is directed
*/
TopologicalSortGraph Graph = new TopologicalSortGraph();
//public LinkedList nodes = new LinkedList();
public static void topologicalSort(Graph graph) {
Queue q = new LinkedList();
int vertexProcessesCtr = 0;
for(Node m : graph.nodes){
if(m.inDegree==0){
++vertexProcessesCtr;
q.add(m);
System.out.println(m.data);
}
}
while(!q.isEmpty()) {
Node m = q.poll();
//System.out.println(m.data);
for(Node child : m.AdjacenctNode){
--child.inDegree;
if(child.inDegree==0){
q.add(child);
++vertexProcessesCtr;
System.out.println(child.data);
}
}
}
if(vertexProcessesCtr > graph.vertices) {
System.out.println();
}
}
public static void main(String[] args) {
Graph g= new Graph();
g.vertices=8;
Node TEN = new Node("10");
Node ELEVEN = new Node("11");
Node TWO = new Node("2");
Node THREE = new Node("3");
Node FIVE = new Node("5");
Node SEVEN = new Node("7");
Node EIGHT = new Node("8");
Node NINE = new Node("9");
SEVEN.AdjacenctNode.add(ELEVEN);
ELEVEN.inDegree++;
SEVEN.AdjacenctNode.add(EIGHT);
EIGHT.inDegree++;
FIVE.AdjacenctNode.add(ELEVEN);
ELEVEN.inDegree++;
THREE.AdjacenctNode.add(EIGHT);
EIGHT.inDegree++;
THREE.AdjacenctNode.add(TEN);
TEN
Solution
class Graph {
public int vertices;
LinkedList nodes = new LinkedList();
}GraphGraph, as other data structures in general, should be declared public. Because you want them to be able to be used outside of the package they are declared in.
nodes, vertices should be private so that you can know that they are not changed outside the
Graph class. nodes should not be a LinkedList. You must depend on abstractions as much as possible. You should prefer
interfaces such as List over specific implementations
LinkedList.Nodes of a graph is not a
List, it is a Set. A standard graph cannot have multiple copies of a node. You should prefer a
Set to represent a set unless you have a good reason.
NodeAll of the above points also apply to
Node. Apart from those: AdjacenctNode should be named adjacentNode by Java naming convention.
Feel free to remove parameterless call to
super();, although Eclipse adds it by default, it's just noise.
TopologicalSortGraphRemove unused code :
TopologicalSortGraph Graph = new TopologicalSortGraph();Always remove commented code. If you need to see previous versions of a
code use a version control system. :
//public LinkedList nodes = new LinkedList();Do not put more than one space between tokens, use autoformat of your
IDE to fix formatting after changing a piece of code:
public static void topologicalSort(Graph graph) {The snippets :
if(child.inDegree==0){
q.add(child);
++vertexProcessesCtr;
System.out.println(child.data);
}and
if(m.inDegree==0){
++vertexProcessesCtr;
q.add(m);
System.out.println(m.data);
}are duplicates. They should be extracted to a
private method. You are missing some kind of abstraction there.
You are changing the internals of an object passed in as a parameter:
--child.inDegree; I do not expect my graph to change after I ask to see its nodes printed in topological order. What if I want to print
them again?
You are mixing the calculation and the printing out of the calculation result,
I do not expect to see
printlns in a method implementing an algorithm: System.out.println( .... );What if I want the result to be printed somewhere other than
System.out? What if I do not want the result to be printed at all and want it to be
used as an intermediate step in a bigger calculation instead?
You probably want to return a
List from a topological sort algorithm.
List is the standard return type when you are sorting some collection, that is when the result is a collection whose order is
important. You can then print that list as many times as you want or
pass it as a parameter to wherever you like.
public static void main(String[] args) {You should separate test code from your main code. If your actual class
is named
TopologicalSortGraph put your test code in TopologicalSortGraphTest. Use de facto standard
JUnit so that instead of one big main you can have many small tests. You can run any one of them or all of them easily
from within your IDE or from the command line.
You should try to separate the test code into separate source
directories or even into separate projects. Your implementation code
should not need or know about your test code to compile.
Another spacing (indentation) problem :
Node TEN = new Node("10");Your code should align well. So that it reads neatly top to bottom and
scopes in it are easily identified.
TEN should be ten by Java naming convention.Instead of these two you should use your
addAdjNode method instead:SEVEN.AdjacenctNode.add(ELEVEN);
ELEVEN.inDegree++;Also access chains like
node.AdjacenctNode.add(otherNode) or x.y.z are usually a sign that your encapsulation is not good enough. In this
case you are modifying a collection of one class from another class.
It's a problem waiting to happen. Same encapsulation problem is present
in
ELEVEN.inDegree++, too. The root problem here is adjacency is a property of the graph -Remember
G = (V, E) from school?- and not of the nodes themselves. Instead of node.addAdjNode(otherNode), you should use a method like graph.addEdge(node, otherNode). Same problem also exists here:
g.nodes.add(TWO); You should have aGraph.addNode(node) method instead. Coming back to
G = (V, E); it says, if you listen carefully, you need a set of vertices and a set of edges to have a graph and should not add
nodes one by one. Ideally,
Graph would have a constructor like this public Graph(Set vertices, Set edges).Code Snippets
class Graph {
public int vertices;
LinkedList<Node> nodes = new LinkedList<Node>();
}TopologicalSortGraph Graph = new TopologicalSortGraph();//public LinkedList<Node> nodes = new LinkedList<Node>();public static void topologicalSort(Graph graph) {if(child.inDegree==0){
q.add(child);
++vertexProcessesCtr;
System.out.println(child.data);
}Context
StackExchange Code Review Q#44689, answer score: 12
Revisions (0)
No revisions yet.