邻接表是图的另一种存储形式,这种方式比较适合稀疏图。
对于稍复杂的问题我喜欢画图来模拟数据的流向,这能够帮我们整理思维,今晚画深度优先遍历的时候,就找出了一个前两天的代码中的一个bug。
package day21;
import datastruct.CircleObjectQueue;
import datastruct.Graph;
import datastruct.ObjectStack;
public class AdjacencyList {
/**
* An inner class for adjacent node.
*
*/
class AdjacencyNode {
/**
* The column index.
*/
int column;
/**
* The next adjacent node.
*/
AdjacencyNode next;
public AdjacencyNode(int paraColumn) {
column = paraColumn;
next = null;
}// Of AdjacencyNode
}// Of class AdjacencyNode
/**
* 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.
*/
AdjacencyNode[] headers;
public AdjacencyList(int[][] paraMatrix) {
numNodes = paraMatrix.length;
// Step 1. Initialize the headers which are not meaningful.
AdjacencyNode tempPreviousNode, tempNode;
headers = new AdjacencyNode[numNodes];
for (int i = 0; i < numNodes; i++) {
headers[i] = new AdjacencyNode(-1);
tempPreviousNode = headers[i];
for (int j = 0; j < numNodes; j++) {
if (paraMatrix[i][j] != 0) {
// Create a new node.
tempNode = new AdjacencyNode(j);
// Link
tempPreviousNode.next = tempNode;
tempPreviousNode = tempNode;
} // Of if
} // Of for j
} // Of for i
}// Of AdjacencyList
public String toString() {
String resultString = "";
AdjacencyNode tempNode;
for (int i = 0; i < numNodes; i++) {
tempNode = headers[i].next;
while (tempNode != null) {
resultString += " (" + i + ", " + tempNode.column + ")";
tempNode = tempNode.next;
} // Of while
resultString += "\r\n";
} // Of for i
return resultString;
}// Of toString
boolean[] visited;
/**
*
*********************
* @Title: initializeVisited
* @Description: TODO(Initialize the visited array.)
*
*********************
*
*/
public void initializeVisited() {
visited = new boolean[numNodes];
for (int i = 0; i < numNodes; i++)
visited[i] = false;
}// Of initializeVisited
/**
*
*********************
* @Title: breadthFirstTraversal
* @Description: TODO(Bread first traversal.)
*
* @param paraIndex The start index.
* @return The sequence of the visit.
*********************
*
*/
public String breadthFirstTraversal(int paraIndex) {
initializeVisited();
String resultString = "";
resultString = breadthFirstTraversal(paraIndex, resultString);
for (int i = 0; i < numNodes; i++) {
if (!visited[i]) {
resultString = breadthFirstTraversal(i, resultString);
} // Of if
} // Of for i
return resultString;
}// Of breadthFirstTraversal
/**
*
*********************
* @Title: breadthFirstTraversal
* @Description: TODO(Bread first traversal.)
*
* @param paraIndex The start index.
* @param paraString The previous sequence of the visit.
* @return The result sequence of the visit.
*********************
*
*/
public String breadthFirstTraversal(int paraIndex, String paraString) {
CircleObjectQueue tempQueue = new CircleObjectQueue();
tempQueue.enqueue(new Integer(paraIndex));
paraString += paraIndex + " ";
visited[paraIndex] = true;
while (!tempQueue.isEmpty()) {
int tempIndex = ((Integer) tempQueue.dequeue()).intValue();
AdjacencyNode tempNode = headers[tempIndex].next;
while (tempNode != null) {
if (!visited[tempNode.column]) {
// Visit before enqueue.
paraString += tempNode.column + " ";
visited[tempNode.column] = true;
tempQueue.enqueue(new Integer(tempNode.column));
} // Of if
tempNode = tempNode.next;
} // Of while
} // Of while
return paraString;
}// Of breadthFirstTraversal
/**
*
*********************
* @Title: breadthFirstTraversalTest
* @Description: TODO(Unit test for breadthFirstTraversal. The same as the one
* in class Graph.)
*
*********************
*
*/
public static void breadthFirstTraversalTest() {
int[][] tempMatrix = { { 0, 1, 1, 0 }, { 1, 0, 0, 1 }, { 1, 0, 0, 1 }, { 0, 1, 1, 0 } };
Graph tempGraph = new Graph(tempMatrix);
System.out.println(tempGraph);
String tempSequence1 = "";
try {
tempSequence1 = tempGraph.breadthFirstTraverse(2);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
} // Of try
System.out.println("The breadth first order of visit with martrix: " + tempSequence1 + "\r\n");
AdjacencyList tempAdjlist = new AdjacencyList(tempMatrix);
String tempSequence2 = "";
try {
tempSequence2 = tempAdjlist.breadthFirstTraversal(2);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
} // Of try
System.out.println("The breadth first order of visit with adjacency list: " + tempSequence2 + "\r\n");
}// Of breadthFirstTraversalTest
/**
*
*********************
* @Title: depthFirstTraversal
* @Description: TODO(Depth first traversal.)
*
* @param paraIndex The start index.
* @return The sequence of the visit.
*********************
*
*/
public String depthFirstTraversal(int paraIndex) {
initializeVisited();
String resultString = "";
resultString = depthFirstTraversal(paraIndex, resultString);
for (int i = 0; i < numNodes; i++) {
if (!visited[i]) {
resultString = depthFirstTraversal(i, resultString);
} // Of if
} // Of for i
return resultString;
}// Of depthFirstTraversal
/**
*
*********************
* @Title: depthFirstTraversal
* @Description: TODO(Depth first traversal.)
*
* @param paraIndex The start index.
* @param paraString The previous sequence of the visit.
* @return The result sequence of the visit.
*********************
*
*/
public String depthFirstTraversal(int paraIndex, String paraString) {
ObjectStack tempStack = new ObjectStack();
paraString += paraIndex + " ";
visited[paraIndex] = true;
tempStack.push(new Integer(paraIndex));
AdjacencyNode tempNode = headers[paraIndex];
boolean fromStack = false;
int tempIndex = -1;
while (tempNode != null) {
tempNode = tempNode.next;
while (tempNode != null) {
if (!visited[tempNode.column]) {
// Push again.
if (fromStack) {
tempStack.push(new Integer(tempIndex));
fromStack = false;
} // Of if
// Visit before push.
paraString += tempNode.column + " ";
visited[tempNode.column] = true;
tempStack.push(new Integer(tempNode.column));
tempNode = headers[tempNode.column].next;
} else {
tempNode = tempNode.next;
} // Of if
} // Of while
if (!tempStack.isEmpty()) {
tempIndex = ((Integer) tempStack.pop()).intValue();
tempNode = headers[tempIndex];
fromStack = true;
} // Of if
} // Of while
return paraString;
}// Of depthFirstTraversal
/**
*
*********************
* @Title: depthFirstTraversalTest
* @Description: TODO(Unit test for depthFirstTraversalTest. The same as the one
* in class Graph.)
*
*********************
*
*/
public static void depthFirstTraversalTest() {
// int[][] tempMatrix = { { 0, 1, 1, 0 }, { 1, 0, 0, 1 }, { 1, 0, 0, 1 }, { 0,
// 1, 1, 0 } };
int[][] tempMatrix = { { 0, 1, 0, 0, 0, 0, 0, 0, 0 }, { 1, 0, 1, 1, 1, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 1, 1, 0, 0 }, { 0, 1, 0, 0, 0, 0, 0, 1, 0 }, { 0, 1, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0 } };
Graph tempGraph = new Graph(tempMatrix);
System.out.println(tempGraph);
String tempSequence1 = "";
try {
tempSequence1 = tempGraph.depthFirstTraverse(0);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
} // Of try
System.out.println("The depth first order of visit with martrix: " + tempSequence1 + "\r\n");
AdjacencyList tempAdjlist = new AdjacencyList(tempMatrix);
String tempSequence2 = "";
try {
tempSequence2 = tempAdjlist.depthFirstTraversal(0);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
} // Of try
System.out.println("The depth first order of visit with adjacency list: " + tempSequence2 + "\r\n");
}// Of depthFirstTraversalTest
public static void main(String args[]) {
// breadthFirstTraversalTest();
depthFirstTraversalTest();
}
}// Of class AdjacencyList
深度优先遍历测试用例图:
运行效果: