java学习16

105 阅读3分钟

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

接昨天内容 对十字链表做了梳理 今天对十字链表构造进行代码分析

代码分析

昨天我们讨论到数组的引用:

a数组引用地址 [I@3339ad8e
a数组引用地址 [I@3339ad8e

看数据赋值的内容:

image.png 所以让数组b直接指向数组a,(我们就可以理解为将a数组起个别名b,他们指向的是同一个对象,这就类似c语言中的指针)所以当b=a实际上是将a的引用地址赋值给b,所以b改动a也会随之改动。

在代码中这里的tempColumnNodes和headers数组就是引用传递,当修改tempColumnNodes时,headers也会随之改动

  OrthogonalNode[] tempColumnNodes = new OrthogonalNode[numNodes];
        for (int i = 0; i < numNodes; i++) {
            tempColumnNodes[i] = headers[i];
        }

十字链表的构造 我觉得十字链表的初始化比之前邻接矩阵和邻接表的初始化都更难,相比领接表容易找到出度,逆邻接表容易找到入度。十字链表即能很容易找到入度也很容易找到出度,所以他的数据结构也复杂一些。结合上面的知识和代码,可以将十字链表的初始化分为两部分,先初始化他的出度的链接,再初始化他入度的链接。

对于初始化出度的链接,判断出度是否为0,可以借助矩阵paraMatrix[i][j] == 0,i行j列表示i是否指向j(即是否以i顶点为弧尾)

对于初始化入度的链接,是遍历每一个头节点所链接的弧节点,使每个弧节点的第三个域去链接弧头相同的节点,其中第一个链接的一定是从头节点出发,其中弧节点的第二个域(即代码中的column)代表的是头节点的位置。如代码中的tempColumnNodes[tempNode.column].nextIn。

链接一个节点后要及时移动位置。感觉这段代码用语言不好描述,一定要图上模拟才更容易理解。

    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) {
                    continue;
                }
 
                tempNode = new OrthogonalNode(i,j);
                tempPreviousNode.nextOut = tempNode;
                tempPreviousNode = tempNode;
            }
        }
 
        //Step3. Link to its in nodes. This step is harder.
        OrthogonalNode[] tempColumnNodes = new OrthogonalNode[numNodes];
        for (int i = 0; i < numNodes; i++) {
            tempColumnNodes[i] = headers[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;
            }
        }
 
    }

测试:

image.png 程序运行的结果:

The data are:
 (0, 1)
 (1, 3)
 (2, 0)
 (3, 1) (3, 2)
 
In arcs:  (2, 0)
 (0, 1) (3, 1)
 (3, 2)
 (1, 3)

总结:

十字链表我感觉比之前的存储结构都复杂,也花了一些时间去理解,在理解十字链表的过程中,画图很重要,如果直接去看代码可能会很吃力,在今天的代码中对节点入度的初始化,只用了几行代码就实现了,但理解时我还是结合图去理解。