zoukankan      html  css  js  c++  java
  • 图(有向)-拓扑排序

    具有优先关系的情况
    有向图的邻接矩阵不是双向的
    具有这样的规则:在某个顶点输出之前,有些顶点必须先输出。
    在图中先找到没有后继顶点的顶点,存入数组中,然后删除。如此循环

    //图的顶点
    public class Vertex {
        public char label;//顶点的标识符
        
        public Vertex(char lab) {//初始化顶点(属性)
            label=lab;
            
            
        }
        
    
    }
    public class Graph {
        private final int MAX_VERTS=20;//最大顶点数
        private Vertex[] vertexList;//顶点数组
        private int [][]adjMat;//顶点关系的领接矩阵(邻接矩阵的每行或者每列的位置跟顶点数组是对应的)
        private int nVerts;//当前顶点个数
        private char[] sortedArray;//用于存放获取到的顶点数组的值(拓扑排序后的结果)
        public Graph() {//初始化图
            vertexList=new Vertex[MAX_VERTS]; //初始化顶点数组
            adjMat=new int [MAX_VERTS][MAX_VERTS] ;//初始化邻接矩阵
            for(int j=0;j<MAX_VERTS;j++)
                for(int i=0;i<MAX_VERTS;i++)
                    adjMat[i][j]=0;
            nVerts=0;//初始化当前顶点个数
            sortedArray=new char[MAX_VERTS];
        }
        //向顶点数组中添加顶点对象
        public void addVertex(char lab) {
            vertexList[nVerts++]=new Vertex(lab);//建立lab对象,往数组内添加
        }
        //添加边(向邻接矩阵中改变数据为1)
        public void addEdge(int start,int end) {
            //因为是有向图所以(i,j)要添加1
            adjMat[start][end]=1;
            
        }
        //打印顶点数组,根据获取的顶点数组的下标值,打印顶点
        public void displayVertex(int v) {
            System.out.print(vertexList[v].label);
        }
        //拓扑排序
        public void topo() {
            int orig_nVerts=nVerts;//记下最初图的顶点数
            while(nVerts>0) {//循环条件,如果图中的顶点数为0,就退出循环
                int currentVertex=noSuccessorts();
                if(currentVertex==-1) {
                    System.out.println("没有存在后继顶点的顶点了 ");
                    return ;
                }
                //将没有后继顶点的数据存入数组中(从后开始存)
                sortedArray[nVerts-1]=vertexList[currentVertex].label;
                //删除该顶点
                deleteVertx(currentVertex);
            }
            for(int i=0;i<orig_nVerts;i++)
                System.out.print(sortedArray[i]);
            System.out.println();
            
        }
        //查找一个没有后继顶点的顶点
        public int noSuccessorts() {
            boolean isEdge;//用于循环查找邻接矩阵过程中的标志
            for(int row=0;row<nVerts;row++) {//遍历邻接矩阵,查找没有后继顶点的顶点(当前行都为0,那就是了)
                isEdge=false;//是true说明该顶点不是要找的,是false,说明当前顶点没有后继
                for(int col=0; col<nVerts;col++) {
                    if(adjMat[row][col]>0) {
                        isEdge=true;
                        break;//退出内层循环,因为只要存在一个就不是要找的顶点
                    }
                }
                if(!isEdge)
                    return row;
            }
            return -1;//说明整个循环都没有找到一个
        }
        //删除一个顶点(需要改变邻接矩阵和顶点顶点数组)
        public void deleteVertx(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-1);
            }
            nVerts--;//删除后需要将当前顶点数减去1,而且这个也是邻接矩阵最后一行的删除方法。
        }
        //移动矩阵中的行一次
        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];
        } 
    
    }
    public class Test {
        public static void main(String[] agrs) {
            Graph theGraph=new Graph();//创建一个图
            theGraph.addVertex('A');//添加顶点
            theGraph.addVertex('B');//添加顶点
            theGraph.addVertex('C');//添加顶点
            theGraph.addVertex('D');//添加顶点
            theGraph.addVertex('E');//添加顶点
            theGraph.addVertex('F');//添加顶点
            theGraph.addVertex('G');//添加顶点
            theGraph.addVertex('H');//添加顶点
            
            theGraph.addEdge(0, 4);//添加边
            theGraph.addEdge(0, 3);//添加边
            theGraph.addEdge(1, 4);//添加边
            theGraph.addEdge(2, 5);//添加边
            theGraph.addEdge(3, 6);//添加边
            theGraph.addEdge(4, 6);//添加边
            theGraph.addEdge(5, 7);//添加边
            theGraph.addEdge(6, 7);//添加边
            theGraph.topo();
            
        }
    
    }
  • 相关阅读:
    兼容python3 小烦
    fstring 和 海象赋值
    Go-gRPC的简单使用
    GO-操作etcd简单示例
    进度报告
    进度报告
    windown 10 安装redis
    在.Net Core中使用T4工具生成实体文件
    python-with关键字,json,pickie序列化与反序列化
    python-文件操作-读,写,追加
  • 原文地址:https://www.cnblogs.com/S-Mustard/p/7687348.html
Copyright © 2011-2022 走看看