1.邻接表
当我们存储图中的数据中时,如果顶点较多,而边数较少时,使用邻接矩阵来存储将极大的浪费空间,而为了解决这种浪费,提出了一种新的存储方式:邻接表。
顾名思义,这种存储方式是依据链式存储的方式从而实现的。将图中的顶点使用一个一维数组进行存储,表中各个节点由data域和next指针域组成,其中data是用来存储节点编号信息,next指向下一个邻接点。
2.代码
在之前的图的广度优先遍历中,使用的是for循环
而今天邻接表中将其for循环改成了while循环
具体代码如下:
package graph;
import tree.CircleObjectQueue;
/**
*
* @author leeyz_1@163.com
*/
public class AdjacencyList {
/**
* An inner class for adjacent node.
*/
class AdjacencyNode {
/**
* The column index.
*/
int column;
/**
* The next adjacent node.
*/
AdjacencyNode next;
/**
*********************
* The first constructor.
*
* @param paraColumn The column.
*********************
*/
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;
/**
*********************
* The first constructor.
*
* @param paraMatrix The the matrix indicating the graph.
* 表示图形的矩阵
*********************
*/
public AdjacencyList(int[][] paraMatrix) {
numNodes = paraMatrix.length;
// Step 1. Initialize. The data in the headers 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];
//找到权值不为0的点,此时找到的是邻接点
for (int j = 0; j < numNodes; j++) {
if (paraMatrix[i][j] == 0) {
continue;
} // Of if
// Create a new node.
tempNode = new AdjacencyNode(j);
// Link.
tempPreviousNode.next = tempNode;
tempPreviousNode = tempNode;
} // Of for j
} // Of for i
}// Of class AdjacentTable
/**
*********************
* Overrides the method claimed in Object, the superclass of any class.
*********************
*/
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
/**
*
***********************************
* @Title: breadthFirstTraversal
* @Description:
* @param: @param paraStartIndex The start index
* @param: @return The sequence of the visit.
* @return: String
***********************************
*/
public String breadthFirstTraversal(int paraStartIndex) {
CircleObjectQueue tempQueue = new CircleObjectQueue();
String resultString = "";
boolean[] tempVisitedArray = new boolean[numNodes];
tempVisitedArray[paraStartIndex] = true;
// Initialize the queue.
// Visit before enqueue.
tempVisitedArray[paraStartIndex] = true;
resultString += paraStartIndex;
tempQueue.enqueue(new Integer(paraStartIndex));
// Now visit the rest of the graph.
int tempIndex;
Integer tempInteger = (Integer) tempQueue.dequeue();
AdjacencyNode tempNode;
while (tempInteger != null) {
tempIndex = tempInteger.intValue();
// Enqueue all its unvisited neighbors. The neighbors are linked
// already.
tempNode = headers[tempIndex].next;
while (tempNode != null) {
if (!tempVisitedArray[tempNode.column]) {
// Visit before enqueue.
tempVisitedArray[tempNode.column] = true;
resultString += tempNode.column;
tempQueue.enqueue(new Integer(tempNode.column));
} // Of if
tempNode = tempNode.next;
} // Of for i
// Take out one from the head.
tempInteger = (Integer) tempQueue.dequeue();
} // Of while
return resultString;
}// Of breadthFirstTraversal
/
/**
*
***********************************
* @Title: breadthFirstTraversalTest
* @Description: Unit test for breadthFirstTraversal. The same as the one in class Graph.
* @param:
* @return: void
***********************************
*/
public static void breadthFirstTraversalTest() {
// Test an undirected graph.
int[][] tempMatrix = { { 0, 1, 1, 0 }, { 1, 0, 0, 1 }, { 1, 0, 0, 1 }, { 0, 1, 1, 0 } };
graph1 tempGraph = new graph1(tempMatrix);
System.out.println(tempGraph);
String tempSequence = "";
try {
tempSequence = tempGraph.breadthFirstTraversal(2);
} catch (Exception ee) {
System.out.println(ee);
} // Of try.
System.out.println("The breadth first order of visit: " + tempSequence);
}// Of breadthFirstTraversalTest
/**
*
***********************************
* @Title: main
* @Description: The entrance of the program.
* @param: @param args
* @return: void
***********************************
*/
public static void main(String args[]) {
int[][] tempMatrix = { { 0, 1, 0 }, { 1, 0, 1 }, { 0, 1, 0 } };
AdjacencyList tempTable = new AdjacencyList(tempMatrix);
System.out.println("The data are:\r\n" + tempTable);
breadthFirstTraversalTest();
}// Of main
}// Of class AdjacencyList
3. 总结
在广度优先遍历中,将以前for循环遍历每一个节点,再挨个寻找每个不为0的边,改成while(tempNode != null),直接就判定了下一个节点与其是否存在相连的边。但是改成了while,它还是挨个在向下遍历不为0的边啊,和以前for循环中的continue效果不是一样的吗?