java学习11

104 阅读2分钟

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

图的广度优先遍历

思路:

结合下图,广度优先遍历假设从a节点出发,a访问后,访问领接点b/c,b访问了再访问c,又接着访问b的领接点,c的领接点,这样一层一层的访问,这就好比树的层次遍历一样。在访问图时要借助一个队列来实现

如图广度优先遍历的一种顺序是:a->b->c->d->e

image.png

代码实现

结合上面的思路和文章来敲代码,在这段代码中,正如文章所说矩阵只要准备好了,写这些代码真的很方便。我感受最深的是:找节点的邻接点,这一行代码就可以去判断节点的领接点

    /**
     *  Breadth first traversal. paraStartIndex The start index.
     * @param paraStartIndex
     * @return
     */
    public String breadthFirstTraversal(int paraStartIndex) {
        CircleQueue tempQueue =  new CircleQueue();
        String resultString = "";
 
        int tempNumNodes = connectivityMatrix.getRows();
        boolean[] tempVisitedArray = new boolean[tempNumNodes];
 
        //Initialize the queue
        tempVisitedArray[paraStartIndex] = true;
        resultString += paraStartIndex;
        tempQueue.enqueue(new Integer(paraStartIndex));
 
        //Now visit the rest of the graph
        int tempIndex;
        Integer tempInteger = (Integer) tempQueue.dequeue();
        while (tempInteger != null) {
            tempIndex = tempInteger.intValue();
 
            //Enqueue all its unvisited neighbors.
            for (int i = 0; i < tempNumNodes; i++) {
                if (tempVisitedArray[i]) {
                    continue;
                }
 
                //Not directly connected
                if (connectivityMatrix.getData()[tempIndex][i] == 0) {
                    continue;
                }
 
                //Visit before enqueue.
                tempVisitedArray[i] = true;
                resultString += i;
                tempQueue.enqueue(new Integer(i));
            }
 
            //Take out one from the head.
            tempInteger = (Integer)tempQueue.dequeue();
        }
 
        return resultString;
    }

结合单元测试的例子画的图如下:

[[0, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]]
No element in the queue
The breadth first order of visit: 2031

判断联通性

在今天的文章中,这个遍历只能遍历连通图(有向图),若是非连通图,则会漏一些节点数据(需要加一个循环来验证节点是否访问完)。在代码中有一个布尔类型数组:boolean[] tempVisitedArray = new boolean[tempNumNodes];若我们在一次广度遍历完遍历这个tempVisitedArray数组,再循环遍历是否有false,若有则说明图是非连通图,这是我们还需要把未遍历的节点再遍历完。我自己写了一个判断连通,这里传了一个参数,为了方便,没有将这个数组设置为成员变量,仅仅只是做了一个测试。

     * Judge connectivity
     * @param tempVisitedArray bool类型 数组
     * @return
     */
    public boolean isConectivity(boolean[] tempVisitedArray) {
        int tempNumNodes = connectivityMatrix.getRows();
        for (int i = 0; i < tempNumNodes; i++){
            if (!tempVisitedArray[i]){
                System.out.println("The graph is not connectivity, The node is " + i);
                return false;
            }
        }
        return true;
    }

总结:

今天主要学习了图的遍历之广度优先遍历算法,结合day32利用矩阵运算可以判断图的连通性,则今天的广度优先遍历算法也可以判断图的连通性,我们只需要再借助一个bool类型的数组即可