概念
十字链表(Orthogonal List)是有向图的另一种链式存储结构。该结构可以看成是将有向图的邻接表(出度)和逆邻接表(入度)结合起来得到的。用十字链表来存储有向图,可以达到高效的存取效果。
简单的说,十字链表是在邻接表的基础上增加了入度的信息。
例子
其邻接表是
逆邻接表是
那么怎么合并
代码
import java.util.ArrayList;
import java.util.List;
class ArcNode{
/** 头节点*/
VertexNode headVec;
/** 尾节点*/
VertexNode tailVec;
int value;
ArcNode hLink;
ArcNode tLink;
}
class VertexNode {
public VertexNode(String name) {
this.name = name;
}
String name;
int value;
/**入度*/
ArcNode firstIn;
/**出度*/
ArcNode firstOut;
}
class OrthogonalList{
int[][] graph;
List<VertexNode> vertexNodes;
public OrthogonalList(int[][] graph,String[] names) {
this.graph = graph;
this.vertexNodes = buildOrthogonalList(graph,names);
}
public List<VertexNode> buildOrthogonalList(int[][] graph,String[] names){
List<VertexNode> vertexNodes = new ArrayList<>();
// 因为一个节点有出度必然会有入度,所以我们需要先对其进行初始化
for(int i=0;i<graph.length;i++){
vertexNodes.add(new VertexNode(names[i]));
}
for(int i=0;i<graph.length;i++){
for(int j=0;j<graph[0].length;j++){
if(graph[i][j]==1){
//有边,那么我们会开始构建
ArcNode arcNode = new ArcNode();
arcNode.headVec = vertexNodes.get(i);
arcNode.tailVec = vertexNodes.get(j);
// i 构建出度
buildNodeOutArc(vertexNodes.get(i),arcNode);
// j 构建入度
buildNodeInArc(vertexNodes.get(j),arcNode);
}
}
}
return vertexNodes;
}
/**
* 构建入度 尾节点一致
*/
public void buildNodeInArc(VertexNode vertexNode,ArcNode arcNode){
if(vertexNode.firstIn==null){
vertexNode.firstIn = arcNode;
return;
}
ArcNode tempArcNode = vertexNode.firstIn;
while (tempArcNode.tLink!=null){
tempArcNode = tempArcNode.tLink;
}
tempArcNode.tLink = arcNode;
}
/**
* 构建出度 头节点一致
*/
public void buildNodeOutArc(VertexNode vertexNode, ArcNode arcNode){
if(vertexNode.firstOut==null){
vertexNode.firstOut = arcNode;
return;
}
ArcNode tempArcNode = vertexNode.firstOut;
while (tempArcNode.hLink!=null){
tempArcNode = tempArcNode.hLink;
}
tempArcNode.hLink = arcNode;
}
/**
* 打印所有节点的出度和入度
*/
public void printAllNodeInAndOut(){
for(VertexNode vertexNode:vertexNodes){
System.out.println("节点: "+vertexNode.name);
ArcNode firstIn = vertexNode.firstIn;
ArcNode firstOut = vertexNode.firstOut;
System.out.println("入度: ");
while (firstIn!=null){
System.out.println(firstIn.headVec.name+"-->"+firstIn.tailVec.name);
firstIn = firstIn.tLink;
}
System.out.println("出度: ");
while (firstOut!=null){
System.out.println(firstOut.headVec.name+"-->"+firstOut.tailVec.name);
firstOut = firstOut.hLink;
}
}
}
}
class testVertexNode{
public static void main(String[] args) {
String[] names = {"v1","v2","v3","v4"};
int[][] graph = {{0,1,1,1},{1,0,0,0},{1,0,0,1},{0,0,0,0}};
OrthogonalList orthogonalList = new OrthogonalList(graph,names);
orthogonalList.printAllNodeInAndOut();
}
}