I am building up a Graph repository which I am planing to use for exploring all the Graph algorithms. This is more from a learning perspective only. I have implemented a basic Graph
class using adjacency list and plan to add to this moving further.
Node.java - essentially will contain all node/vertex related information
class Node {
String nodeData;
int nodeNumber;
boolean isVisited;
Node next;
Node( String theNodeData, int nodeNum ) {
this.nodeData = theNodeData;
this.nodeNumber = nodeNum;
}
Node(int nodeNumber) {
this.nodeNumber = nodeNumber;
}
Node() {
this.nodeData = null;
this.nodeNumber=0;
this.isVisited=false;
this.next=null;
}
}
Graph.java
public class Graph {
private int totalNoOfNodes;
private static boolean isDirected;
private HashMap<Integer,ArrayList<Node>> adjacencyListMap;
private HashMap<String,Integer> nameToNodeMap;//Map Node data to integer(vertex)
private Map<Integer,String> nodeToNameMap;// Map vertex or node number to corresponding node data
public Graph(String inputFileName) throws FileNotFoundException {
Scanner sc = new Scanner(new File(inputFileName));
String orientation = sc.next();
if("directed".equals(orientation)) {
// Graph is directed
isDirected = true;
} else {
isDirected = false;
}
adjacencyListMap = new HashMap<Integer,ArrayList<Node>>();
nameToNodeMap = new HashMap<String,Integer>();
nodeToNameMap = new HashMap<Integer,String>();
int numberOfNodes = sc.nextInt();
this.totalNoOfNodes = numberOfNodes;
for ( int i =0; i < totalNoOfNodes; ++i ) {
ArrayList<Node> neighbours = new ArrayList<Node>();
adjacencyListMap.put(i, neighbours);
}
for ( int i =0; i < totalNoOfNodes; ++i) {
nameToNodeMap.put(sc.next(), i);
}
while ( sc.hasNext() ) {
String nameOne = sc.next();
String nameTwo = sc.next();
int source = nameToNodeMap.get(nameOne);
nodeToNameMap.put(source, nameOne);
int destination = nameToNodeMap.get(nameTwo);
nodeToNameMap.put(destination, nameTwo);
addEdges(source,nameOne, destination, nameTwo);
}
sc.close();
}
private void addEdges(int source,String nameOne, int destination,String nameTwo) {
if ( source > adjacencyListMap.size() || destination > adjacencyListMap.size() ) {
throw new IllegalArgumentException("Source/Destination Vertex invalid. Cannot add edge.");
}
(adjacencyListMap.get(source)).add(new Node(nameTwo,destination));
if ( ! isDirected ) {
(adjacencyListMap.get(destination)).add(new Node(nameOne,source));
}
}
public int getIndexFromNames(String name ) {
for ( int i =0; i < adjacencyListMap.size(); ++i ) {
if ( adjacencyListMap.get(i).equals(name) ) {
return i;
}
}
return -1;
}
public ArrayList<Node> getAdjacentNodesOf(int source) {
return adjacencyListMap.get(source);
}
public int getTotalNoOfNodesInGraph() {
return totalNoOfNodes;
}
}
Basic test data
undirected
10
Sara
Sam
Sean
Ajay
Mira
Jane
Maria
Rahul
Sapna
Rohit
Sara Sam
Sara Ajay
Sam Sean
Sam Mira
Mira Jane
Jane Maria
Rahul Sapna
Sapna Rohit
- Graph.java will serve as a basic data type.
- Specific algorithms will be in corresponding classes, say for example DijikstraShortestPath.java and IsGraphAcyclic.java. The underlying data structure used by these algorithms will be Graph.java.
Questions:
- What do you think of the overall approach? My idea is to just explore various graph algorithms and learn their implementation during the process.
- Will incorporating generics be of any use?
- Any pointers on how the code could be improved?