java学习14

106 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

邻连表

领接表

领接表也是图的一种存储结构,之前的存储是领接矩阵。领接表是数组和链表的结合,其中有一个顶点数组和边表组成,如下图所示。对于稀疏图,如果用领接矩阵,有10个节点,则需要10*10的空间,但利用率很低,但是对于邻接表的存储可能需要的空间更少。

image.png

结合上图去抽象一个邻接表结点的对象

(1): 对于顶点数组中,每个结点存的是结点的值,而在边表中的每个结点存储的是顶点数组的下标位置 所以对结点的抽象数据就有一个column和一个next:

        /**
         * The column index.
         */
        int column;
        /**
         *  The next adjacent node.
         */
        AdjacencyNode next;
 
        /**
         * The first constructor.
         * @param paraColumn
         */
        public AdjacencyNode(int paraColumn){
            column = paraColumn;
            next = null;
        }
    }

(2) 对于一个邻接表的构造,从代码中可以知道,对于headers数组的colun设置 为-1,并没有存放数据。我们是取的下标索引作为节点的值。在这个构造函数中,tempPreviousNodetempNode两个变量让顶点数组和边表连接起来了。

    AdjacencyNode[] headers;
 
    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];
            for (int j = 0; j < numNodes; j++){
                if (paraMatrix[i][j] == 0){
                    continue;
                }
 
                // Create a new node.
                tempNode = new AdjacencyNode(j);
 
                // Link.
                tempPreviousNode.next = tempNode;
                tempPreviousNode = tempNode;
            }
        }
    }

可以看一下这个在初始化后的结构:

AdjacencyList tempTable = new AdjacencyList(tempMatrix);

打断点看headers数据结构。

image.png 返回的headers数组和下图的表一样

image.png (3)两种不同存储结构的广度优先遍历 对于矩阵的存储结构:我们对每一行数据for循环去判断结点是否被访问,结点是否相邻?之后再访问结点入队列

对于领接表存储结构:我们是对每一个hearders[i]所连接的链表,只需要判断结点是否访问,不用再判断结点相邻,因为这链表连接的就是领接点。 之后就访问结点入队列。

总结

今天主要是学习邻接表的存储结构。变换为邻接表的广度优先遍历