zoukankan      html  css  js  c++  java
  • 图(二)

    最小生成的树

    图中的所有顶点(V)只用最少数量的边(E)保证它们彼此连通,就组成最小生成的树。

    注意,最小生成的树边(E)的数量总比顶点(V)的数量少1,即:E = V - 1 ;

    记住,不必关心边的长度,不需要找到最短路径,而是找最少数量的边。(在带权图中会发生改变)

    创建最小生成的树的算法与遍历几乎相同,它同样可以基于深度优先遍历或广度优先遍历。下面是基于深度优先遍历的代码:

        public void mst(){
            vertexArray[0].setVisited(true);
            stack.push(0);
    
            while (!stack.isEmpty()) {
                int currentVertex = stack.peek();
                int v = getAdjUnvisitedVertex(currentVertex);
                if (v == -1) {
                    stack.pop();
                }
                else {
                    vertexArray[v].setVisited(true);
                    stack.push(v);
                    displayVertex(currentVertex);
                    displayVertex(v);
                }
            }
    
            for (int j = 0; j < MAX_VERTS; j++) {
                if (vertexArray[j] != null) {
                    vertexArray[j].setVisited(false);
                }
            }
        }

     

    有向图的拓扑排序

    有向图:边有方向,只能沿着边的方向移动。以下是邻接矩阵:

           A      B      C
        A      0      1      0
        B      0      0      1
        C      0      0      0

                 如图:

    1 表示一条边,行标表示从哪里开始,列标表示到哪里结束。例如图中 A -> B,只有行A到列B的值为1,行B到列A的值为0。

    邻接表:

      顶点      包含邻接顶点的链表
       A      B  
       B      C
       C  

         不同于无向图是:B链表中不存在A,C链表中不存在B。

    拓扑排序

    后继:若有一条边从A指向B,那么B就是A的后继。

    环:它是一条路径,路径的起点和终点在同一个顶点。例如:A -> B -> C -> D -> A,但是 A -> B -> C,A -> D 不是环。

    步骤

    1. 找到没有后继的顶点
    2. 从图中删除这个顶点,在列表的前面插入顶点的标记。
    3. 重复步骤1、2,直到所有顶点都从图中删除。这时列表显示的顶点顺序就是拓扑排序。
    public class Vertex {
    
        private char label;
    
        public Vertex(char label) {
            this.label = label;
        }
    
        public char getLabel() {
            return label;
        }
    
    }
    public class Graph {
    
        private final int MAX_VERTS;
    
        private Vertex[] vertexList;
    
        private int[][] adjMat;
    
        private int nVerts;
    
        private char[] sortedList;
    
        public Graph(int verts) {
            this.MAX_VERTS = verts;
            vertexList = new Vertex[MAX_VERTS];
            sortedList = new char[MAX_VERTS];
            adjMat = new int[MAX_VERTS][MAX_VERTS];
            nVerts = 0;
        }
    
        public void addVertex(char label) {
            vertexList[nVerts++] = new Vertex(label);
        }
    
        public void addEdge(int start, int end) {
            adjMat[start][end] = 1;
        }
    
        public void topo() {
            int orig_Verts = nVerts;
            /*
             * 1、调用noSuccessors()找到任意一个没有后继的顶点。
             * 2、将该顶点放入sortedList,并把它从图中删除。
             * 3、如果没有这样的顶点,必然出现环。
             * */
            while (nVerts > 0) {
                int currentVertex = noSuccessors();
                if (currentVertex == -1) {
                    System.out.println("error : cycle .");
                    return;
                }
                sortedList[nVerts - 1] = vertexList[currentVertex].getLabel();
                deleteVertex(currentVertex);
            }
            System.out.print("sort order : ");
            for (int i = 0; i < orig_Verts; i++) {
                System.out.print(sortedList[i]);
            }
            System.out.print(" . ");
        }
    
        public int noSuccessors() {
            boolean isEdge;
            for (int row = 0; row < nVerts; row++) {
                isEdge = false;
                for (int col = 0; col < nVerts; col++) {
                    if (adjMat[row][col] > 0) {
                        isEdge = true;
                        break;
                    }
                }
                if (!isEdge) {
                    return row;
                }
            }
            return -1;
        }
    
        public void deleteVertex(int delVert) {
            if (delVert != nVerts - 1) {
                for (int j = delVert; j < nVerts - 1; j++)
                    vertexList[j] = vertexList[j + 1];
                for (int row = delVert; row < nVerts - 1; row++)
                    moveRowUp(row, nVerts);
                for (int col = delVert; col < nVerts - 1; col++)
                    moveColLeft(col, nVerts);
            }
            nVerts--;
        }
    
        private void moveRowUp(int row, int length) {
            for (int col = 0; col < length; col++) {
                adjMat[row][col] = adjMat[row + 1][col];
            }
        }
    
        private void moveColLeft(int col, int length) {
            for (int row = 0; row < length; row++) {
                adjMat[row][col] = adjMat[row][col + 1];
            }
        }
        
    }

        图z

    有向图的连通性

  • 相关阅读:
    echarts 立体图
    css 设置边框边角
    PS2020 快速设置文字渐变
    idea 2019 永久破解
    使用VUE+element ui 实现输入框 占位符自动补全功能
    纯css 设置隔行样式
    CSS 设置float:left 导致后面元素错乱问题
    c primer plus 4编程练习
    c语言中以八进制数表示字符、并输出
    c语言中printf()函数的返回值
  • 原文地址:https://www.cnblogs.com/xuekyo/p/2913979.html
Copyright © 2011-2022 走看看