图的邻接矩阵和遍历 拓扑排序 java

图的表示有三种,邻接表,邻接矩阵和十字链表

我使用邻接矩阵表示图

邻接矩阵中[i][j]表示i节点指向j节点,大小为[i][j]的值

比如这样

若是无向图,矩阵则是按照对角线对称的。

首先是深度遍历,深度遍历是沿着一个节点往下走,当某个节点的下一个节点被访问过,或者就没有下一个节点时,返回。

和二叉树的深度遍历类似,使用递归

    /**
     * 深度遍历
     */
    @Override
    public void dfsGraph() {
        visit = new int[nodeNumbers];
        for (int i = 0; i < nodeNumbers; i++) {
            visit[i] = 0;
        }
        for (int i = 0; i < nodeNumbers; i++) {
            if (visit[i] != 1)
                dfs(i);
        }
    }

    public void dfs(int i) {
        visit[i] = 1;
        System.out.println(i);
        for (int j = 0; j < nodeNumbers; j++) {
            if (graphMatrix[i][j] != 0 && visit[j] != 1) {
                dfs(j);
            }
        }
    }

广度遍历

广度遍历也和二叉树的类似,把一个节点的出度节点都访问完,再访问下一个节点的,使用队列

    /**
     * 广度优先遍历
     */
    @Override
    public void bfsGraph() {
        ArrayDeque<Integer> bfs = new ArrayDeque<>();
        visit = new int[nodeNumbers];
        for (int i = 0; i < nodeNumbers; i++) {
            visit[i] = 0;
        }
        for (int i = 0; i < nodeNumbers; i++) {
            if (visit[i] == 0) {
                bfs.addFirst(i);
                visit[i] = 1;
                while (!bfs.isEmpty()) {
                    int j = bfs.removeLast();

                    System.out.println(j);
                    for (int m = 0; m < nodeNumbers; m++) {
                        if (visit[m] != 1 && graphMatrix[j][m] != 0) {
                            bfs.addFirst(m);
                            visit[m] = 1;
                        }
                    }
                }
            }
        }


    }

拓扑排序

会问到的还有拓扑排序,拓扑排序可以解决有向图中是否存在环的问题

其基本思想:

        拓扑排序的基本操作为:

1.从图中选择一个入度为0的顶点并且输出它;

2.从图中删除此顶点及所有由它发出的边;

3.重复上述过程,直到图中没有入度为0的边。

因此,当有向图中存在环的时候,几个节点会相互存在出度,会删除不掉,所以拓扑排序可以判断是否有环

 /**
     * 拓扑排序
     */
    @Override
    public void TopologicalGraph() {
        visit = new int[nodeNumbers];

        for (int i = 0; i < nodeNumbers; i++) {
            visit[i] = 0;
        }
        for (int n = 0; n < nodeNumbers; n++) {

            for (int i = 0; i < nodeNumbers; i++) {
                boolean haveOut = true;
                for (int j = 0; j < nodeNumbers; j++) {
                    if (graphMatrix[j][i] != 0) {
                        haveOut = false;
                        break;
                    }
                }
                if (visit[i] == 0 && haveOut) {
                    visit[i] = 1;
                    System.out.println(i);
                    for (int m = 0; m < nodeNumbers; m++) {
                        graphMatrix[i][m] = 0;
                        graphMatrix[m][i] = 0;
                    }
                    break;
                }
            }
        }

    }

图的构建:

public class GraphMatrixImpl implements GraphMatrix {
    private int nodeNumbers;
    private int[][] graphMatrix;
    private int[] visit;

    public GraphMatrixImpl(int nodeNumbers) {
        graphMatrix = new int[nodeNumbers][nodeNumbers];
        this.nodeNumbers = nodeNumbers;
    }

    @Override
    public void addBrim(int firstNode, int secondNode, int value) {
        if (firstNode >= nodeNumbers && secondNode >= nodeNumbers) return;
        graphMatrix[firstNode][secondNode] = value;
        //graphMatrix[secondNode][firstNode] = value;
    }

    @Override
    public void deleteBrim(int firstNode, int secondNode, int value) {
        if (firstNode >= nodeNumbers && secondNode >= nodeNumbers) return;
        graphMatrix[firstNode][secondNode] = 0;
        graphMatrix[secondNode][firstNode] = 0;
    }

    @Override
    public void display() {
        for (int i = 0; i < nodeNumbers; i++) {
            for (int j = 0; j < nodeNumbers; j++) {
                System.out.print(graphMatrix[i][j] + " ");
            }
            System.out.println("");
        }
    }

    /**
     * 深度遍历
     */
    @Override
    public void dfsGraph() {
        visit = new int[nodeNumbers];
        for (int i = 0; i < nodeNumbers; i++) {
            visit[i] = 0;
        }
        for (int i = 0; i < nodeNumbers; i++) {
            if (visit[i] != 1)
                dfs(i);
        }
    }

    public void dfs(int i) {
        visit[i] = 1;
        System.out.println(i);
        for (int j = 0; j < nodeNumbers; j++) {
            if (graphMatrix[i][j] != 0 && visit[j] != 1) {
                dfs(j);
            }
        }
    }

    /**
     * 广度优先遍历
     */
    @Override
    public void bfsGraph() {
        ArrayDeque<Integer> bfs = new ArrayDeque<>();
        visit = new int[nodeNumbers];
        for (int i = 0; i < nodeNumbers; i++) {
            visit[i] = 0;
        }
        for (int i = 0; i < nodeNumbers; i++) {
            if (visit[i] == 0) {
                bfs.addFirst(i);
                visit[i] = 1;
                while (!bfs.isEmpty()) {
                    int j = bfs.removeLast();

                    System.out.println(j);
                    for (int m = 0; m < nodeNumbers; m++) {
                        if (visit[m] != 1 && graphMatrix[j][m] != 0) {
                            bfs.addFirst(m);
                            visit[m] = 1;
                        }
                    }
                }
            }
        }


    }


    /**
     * 拓扑排序
     */
    @Override
    public void TopologicalGraph() {
        visit = new int[nodeNumbers];

        for (int i = 0; i < nodeNumbers; i++) {
            visit[i] = 0;
        }
        for (int n = 0; n < nodeNumbers; n++) {

            for (int i = 0; i < nodeNumbers; i++) {
                boolean haveOut = true;
                for (int j = 0; j < nodeNumbers; j++) {
                    if (graphMatrix[j][i] != 0) {
                        haveOut = false;
                        break;
                    }
                }
                if (visit[i] == 0 && haveOut) {
                    visit[i] = 1;
                    System.out.println(i);
                    for (int m = 0; m < nodeNumbers; m++) {
                        graphMatrix[i][m] = 0;
                        graphMatrix[m][i] = 0;
                    }
                    break;
                }
            }
        }

    }
}

参考:

https://blog.csdn.net/tengweitw/article/details/17265961

猜你喜欢

转载自blog.csdn.net/zyh568879280/article/details/88079128