十字链表 java

概念

十字链表(Orthogonal List)是有向图的另一种链式存储结构。该结构可以看成是将有向图的邻接表(出度)和逆邻接表(入度)结合起来得到的。用十字链表来存储有向图,可以达到高效的存取效果。

简单的说,十字链表是在邻接表的基础上增加了入度的信息。

例子

十字链表 java

其邻接表是
十字链表 java

逆邻接表是

十字链表 java

那么怎么合并
十字链表 java

代码

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();
    }
}
上一篇:【异常检测】恶意软件检测:MaMaDroid (DNSS 2017)


下一篇:图论算法遍历基础