/** * Orthogonal List for directed graph. * * @author ShiHuai Wen shihuaiwen@outlook.com. */ publicclassOrthogonalList { /** * An inner class for adjacent node. */ classOrthogonalNode { /** * The row index. */ int row;
/** * The column index. */ int column;
/** * The next out node. */ OrthogonalNode nextOut;
/** * The next in node. */ OrthogonalNode nextIn;
/** ********************* * The first constructor. * * @param paraRow The row. * @param paraColumn The column. ********************* */ publicOrthogonalNode(int paraRow, int paraColumn) { row = paraRow; column = paraColumn; nextOut = null; nextIn = null; }// Of OrthogonalNode }// Of class OrthogonalNode
/** * The number of nodes. This member variable may be redundant since it is always * equal to headers.length. */ int numNodes;
/** * The headers for each row. */ OrthogonalNode[] headers;
/** ********************* * The first constructor. * * @param paraMatrix The matrix indicating the graph. ********************* */ publicOrthogonalList(int[][] paraMatrix) { numNodes = paraMatrix.length;
// Step 1. Initialize. The data in the headers are not meaningful. OrthogonalNode tempPreviousNode, tempNode;
headers = newOrthogonalNode[numNodes];
// Step 2. Link to its out nodes. for (inti=0; i < numNodes; i++) { headers[i] = newOrthogonalNode(i, -1); tempPreviousNode = headers[i]; for (intj=0; j < numNodes; j++) { if (paraMatrix[i][j] == 0) { continue; } // Of if
// Create a new node. tempNode = newOrthogonalNode(i, j);
// Link. tempPreviousNode.nextOut = tempNode; tempPreviousNode = tempNode; } // Of for j } // Of for i
// Step 3. Link to its in nodes. This step is harder. OrthogonalNode[] tempColumnNodes = newOrthogonalNode[numNodes]; for (inti=0; i < numNodes; i++) { tempColumnNodes[i] = headers[i]; } // Of for i
for (inti=0; i < numNodes; i++) { tempNode = headers[i].nextOut; while (tempNode != null) { tempColumnNodes[tempNode.column].nextIn = tempNode; tempColumnNodes[tempNode.column] = tempNode;
tempNode = tempNode.nextOut; } // Of while } // Of for i }// Of the constructor
/** ********************* * Overrides the method claimed in Object, the superclass of any class. ********************* */ public String toString() { StringresultString="Out arcs: ";
OrthogonalNode tempNode; for (inti=0; i < numNodes; i++) { tempNode = headers[i].nextOut;
while (tempNode != null) { resultString += " (" + tempNode.row + ", " + tempNode.column + ")"; tempNode = tempNode.nextOut; } // Of while resultString += "\r\n"; } // Of for i
resultString += "\r\nIn arcs: ";
for (inti=0; i < numNodes; i++) { tempNode = headers[i].nextIn;
while (tempNode != null) { resultString += " (" + tempNode.row + ", " + tempNode.column + ")"; tempNode = tempNode.nextIn; } // Of while resultString += "\r\n"; } // Of for i
return resultString; }// Of toString
/** ********************* * The entrance of the program. * * @param args Not used now. ********************* */ publicstaticvoidmain(String args[]) { int[][] tempMatrix = { { 0, 1, 0, 0 }, { 0, 0, 0, 1 }, { 1, 0, 0, 0 }, { 0, 1, 1, 0 } }; OrthogonalListtempList=newOrthogonalList(tempMatrix); System.out.println("The data are:\r\n" + tempList); }// Of main } // Of class OrthogonalList
/** ********************* * The Dijkstra algorithm: shortest path from the source to all nodes. * * @param paraSource The source node. * @return The distances to all nodes. ********************* */ publicint[] dijkstra(int paraSource) { // Step 1. Initialize. int[] tempDistanceArray = newint[numNodes]; for (inti=0; i < numNodes; i++) { tempDistanceArray[i] = weightMatrix.getValue(paraSource, i); } // Of for i
int[] tempParentArray = newint[numNodes]; Arrays.fill(tempParentArray, paraSource); // -1 for no parent. tempParentArray[paraSource] = -1;
// Visited nodes will not be considered further. boolean[] tempVisitedArray = newboolean[numNodes]; tempVisitedArray[paraSource] = true;
// Step 2. Main loops. int tempMinDistance; inttempBestNode= -1; for (inti=0; i < numNodes - 1; i++) { // Step 2.1 Find out the best next node. tempMinDistance = Integer.MAX_VALUE; for (intj=0; j < numNodes; j++) { // This node is visited. if (tempVisitedArray[j]) { continue; } // Of if
if (tempMinDistance > tempDistanceArray[j]) { tempMinDistance = tempDistanceArray[j]; tempBestNode = j; } // Of if } // Of for j
tempVisitedArray[tempBestNode] = true;
// Step 2.2 Prepare for the next round. for (intj=0; j < numNodes; j++) { // This node is visited. if (tempVisitedArray[j]) { continue; } // Of if
// This node cannot be reached. if (weightMatrix.getValue(tempBestNode, j) >= MAX_DISTANCE) { continue; } // Of if
if (tempDistanceArray[j] > tempDistanceArray[tempBestNode] + weightMatrix.getValue(tempBestNode, j)) { // Change the distance. tempDistanceArray[j] = tempDistanceArray[tempBestNode] + weightMatrix.getValue(tempBestNode, j); // Change the parent. tempParentArray[j] = tempBestNode; } // Of if } // Of for j
// For test System.out.println("The distance to each node: " + Arrays.toString(tempDistanceArray)); System.out.println("The parent of each node: " + Arrays.toString(tempParentArray)); } // Of for i
// Step 3. Output for debug. System.out.println("Finally"); System.out.println("The distance to each node: " + Arrays.toString(tempDistanceArray)); System.out.println("The parent of each node: " + Arrays.toString(tempParentArray)); return tempDistanceArray; }// Of dijkstra
/** ********************* * The minimal spanning tree. * * @return The total cost of the tree. ********************* */ publicintprim() { // Step 1. Initialize. // Any node can be the source. inttempSource=0; int[] tempDistanceArray = newint[numNodes]; for (inti=0; i < numNodes; i++) { tempDistanceArray[i] = weightMatrix.getValue(tempSource, i); } // Of for i
int[] tempParentArray = newint[numNodes]; Arrays.fill(tempParentArray, tempSource); // -1 for no parent. tempParentArray[tempSource] = -1;
// Visited nodes will not be considered further. boolean[] tempVisitedArray = newboolean[numNodes]; tempVisitedArray[tempSource] = true;
// Step 2. Main loops. int tempMinDistance; inttempBestNode= -1; for (inti=0; i < numNodes - 1; i++) { // Step 2.1 Find out the best next node. tempMinDistance = Integer.MAX_VALUE; for (intj=0; j < numNodes; j++) { // This node is visited. if (tempVisitedArray[j]) { continue; } // Of if
if (tempMinDistance > tempDistanceArray[j]) { tempMinDistance = tempDistanceArray[j]; tempBestNode = j; } // Of if } // Of for j
tempVisitedArray[tempBestNode] = true;
// Step 2.2 Prepare for the next round. for (intj=0; j < numNodes; j++) { // This node is visited. if (tempVisitedArray[j]) { continue; } // Of if
// This node cannot be reached. if (weightMatrix.getValue(tempBestNode, j) >= MAX_DISTANCE) { continue; } // Of if
// Attention: the difference from the Dijkstra algorithm. if (tempDistanceArray[j] > weightMatrix.getValue(tempBestNode, j)) { // Change the distance. tempDistanceArray[j] = weightMatrix.getValue(tempBestNode, j); // Change the parent. tempParentArray[j] = tempBestNode; } // Of if } // Of for j
// For test System.out.println("The selected distance for each node: " + Arrays.toString(tempDistanceArray)); System.out.println("The parent of each node: " + Arrays.toString(tempParentArray)); } // Of for i
intresultCost=0; for (inti=0; i < numNodes; i++) { resultCost += tempDistanceArray[i]; } // Of for i
// Step 3. Output for debug. System.out.println("Finally"); System.out.println("The parent of each node: " + Arrays.toString(tempParentArray)); System.out.println("The total cost: " + resultCost);