十字链表(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(); } }