十字链表相对比邻接表难一点,相较而言,十字链表的结点比邻接表多了一个指针域用来链接指向该“头”结点的其它结点。
如何实现十字链表,我们可以从实现邻接表找突破口,因为实现邻接表就确定了各个结点的nextOut值,接下来我们只需要确定各个结点的nextIn。
1:确定各个顶点的nextOut:按行遍历邻接矩阵,创建以当前行结点为起点的边结点对象并确定nextOut值:
对应代码:
for (int i = 0; i < numNodes; i++) {
headers[i] = new OrthogonalNode(i, -1);
tempPreviousNode = headers[i];
for (int j = 0; j < numNodes; j++) {
if (paraMatrix[i][j] != 0) {
// Create a new node.
tempNode = new OrthogonalNode(i, j);
// Link
tempPreviousNode.nextOut = tempNode;
tempPreviousNode = tempNode;
} // Of if
} // Of for j
} // Of for i
2:确定每个顶点的nextIn:遍历每个边结点,每个边结点的column值说明了该column对应的结点的nextIn应该指向当前边结点,但需要注意的是,我们只能第一次通过column从header数组里面找到对应结点,如果当前column结点的入度大于1,则需要遍历当前结点nextIn所指向的链表,直到遍历到结点的nextIn为空时再赋值(除非我们用头插法)。为了避免遍历寻找需要插入nextIn的结点,可以为每个顶点设置临时指针,该指针指向当前应该插入nextIn的结点,插入后更新,初始值为顶点结点,使用空间换时间。
为每个顶点设置临时指针的作用:
确定各个结点的nextIn。
对应代码:
OrthogonalNode[] tempColumnNodes = new OrthogonalNode[numNodes];
for (int i = 0; i < numNodes; i++) {
tempColumnNodes[i] = headers[i];
} // Of for i
for (int i = 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
完整代码:
package day22;
public class OrthogonalList {
/**
* An inner class for adjacent node.
*/
class OrthogonalNode {
/**
* 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.
*********************
*
*/
public OrthogonalNode(int paraRow, int paraColumn) {
row = paraRow;
column = paraColumn;
nextIn = null;
nextOut = 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.
*********************
*
*/
public OrthogonalList(int[][] paraMatrix) {
numNodes = paraMatrix.length;
// Step 1. Initialize. The data in the headers are not meaningful.
OrthogonalNode tempPreviousNode, tempNode;
headers = new OrthogonalNode[numNodes];
// Step 2. Link to its out nodes.
for (int i = 0; i < numNodes; i++) {
headers[i] = new OrthogonalNode(i, -1);
tempPreviousNode = headers[i];
for (int j = 0; j < numNodes; j++) {
if (paraMatrix[i][j] != 0) {
// Create a new node.
tempNode = new OrthogonalNode(i, j);
// Link
tempPreviousNode.nextOut = tempNode;
tempPreviousNode = tempNode;
} // Of if
} // Of for j
} // Of for i
// Step 3. Link to its in nodes.
OrthogonalNode[] tempColumnNodes = new OrthogonalNode[numNodes];
for (int i = 0; i < numNodes; i++) {
tempColumnNodes[i] = headers[i];
} // Of for i
for (int i = 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 OrthogonalList
/**
*********************
* Overrides the method claimed in Object, the superclass of any class.
*********************
*/
public String toString() {
String resultString = "Out arcs: \r\n";
OrthogonalNode temNode;
for (int i = 0; i < numNodes; i++) {
temNode = headers[i].nextOut;
while (temNode != null) {
resultString += "(" + temNode.row + "," + temNode.column + ") ";
temNode = temNode.nextOut;
} // Of while
if (headers[i].nextOut != null) {
resultString += "\r\n";
} // Of if
} // Of for i;
resultString += "In arcs: \r\n";
for (int i = 0; i < numNodes; i++) {
temNode = headers[i].nextIn;
while (temNode != null) {
resultString += "(" + temNode.row + "," + temNode.column + ") ";
temNode = temNode.nextIn;
} // Of while
if (headers[i].nextIn != null) {
resultString += "\r\n";
} // Of if
} // Of for i;
return resultString;
}// Of toString
/**
*
*********************
* @Title: main
* @Description: TODO(The entrance of the program.)
*
* @param argsn Not used now.
*********************
*
*/
public static void main(String args[]) {
// int[][] tempMatrix = { { 0, 1, 0, 0 }, { 0, 0, 0, 1 }, { 1, 0, 0, 0 }, { 0,
// 1, 1, 0 } };
int[][] tempMatrix = { { 0, 1, 1, 0 }, { 0, 0, 0, 0 }, { 1, 0, 0, 1 }, { 1, 1, 1, 0 } };
OrthogonalList tempList = new OrthogonalList(tempMatrix);
System.out.println("The data are:\r\n" + tempList);
}// Of main
}// Of class OrthogonalList
运行结果: