`
128kj
  • 浏览: 583809 次
  • 来自: ...
社区版块
存档分类
最新评论

无前趋的顶点优先的拓扑排序方法(JAVA)

    博客分类:
阅读更多
无前趋的顶点优先的拓扑排序方法

    该方法的每一步总是输出当前无前趋(即人度为零)的顶点,其抽象算法可描述为:
    NonPreFirstTopSort(G){//优先输出无前趋的顶点
      while(G中有人度为0的顶点)do{
       从G中选择一个人度为0的顶点v且输出之;
       从G中删去v及其所有出边;
       }
      if(输出的顶点数目<|V(G)|)
        //若此条件不成立,则表示所有顶点均已输出,排序成功。
        Error("G中存在有向环,排序失败!");
     }


import java.util.Arrays;   
import java.util.List;   
import java.util.ArrayList;   
import java.util.Stack;

public class Graph {   
  
    int vertexNum;   //图的顶点数
    ArrayList<ArrayList<Integer>>  table; //图的邻接表,table.get(i)存放与i邻接的顶点
    Stack<Integer> stack;  //存放入度为0的顶点 
    int[] result;   //拓朴排序的结果
    int[] in;// 入度,in[i]表示顶点i的入度   
  
    /**  
     *   
     * 构造一个图  
     *   
     * @param num  
     * 图的顶点数  
     *   
     */  
    public Graph(int num) {   
  
        vertexNum = num;   
        table = new ArrayList<ArrayList<Integer>> (vertexNum);   
         for(int i=0;i<vertexNum;i++)
              table.add(new ArrayList<Integer>());
        stack = new Stack<Integer>();   
        result = new int[vertexNum];   
        in = new int[vertexNum];   
  
    }   
  
    /**  
     * 向图中添加无向边  
     *   
     * @param I  
     *         边的一个顶点  
     * @param J  
     *         边的另一个顶点  
     * @return 是否添加成功  
     */  
    public boolean addEdge(int I, int J) {   
  
        /**  
         * 判断用户输入的是否是一个顶点,如果是,则返回flase,添加不成功  
         */  
        if (J == I) {   
            return false;   
        }   
  
        /**  
         * 判断所输入的顶点值是否在图所顶点范围值内,如果不在,则提示顶点不存在  
         *   
         */  
        if (I < vertexNum && J < vertexNum && I >= 0 && J >= 0) {    
            /**  
             *   
             * 判断边是否存在  
             */  
  
            if (isEdgeExists(I, J)) {    
                return false;   
            }   
  
            /**  
             * 添加边,将孤头的入度加1  
             */  
  
            table.get(I).add(J);   
            in[J]++;   
            return true;   
        }   
        return false;   
    }   
  
    /**  
     * 判断有向边是否存在  
     *   
     * @param i  
     *            要查询的有向边的一个孤尾  
     * @param j  
     *            要查询的有向边的另一个孤头  
     * @return 边是否存在,false:不存在,true:存在  
     */  
  
    public boolean isEdgeExists(int i, int j) {   
  
        /**  
         * 判断所输入的顶点值是否在图所顶点范围值内,如果不在,则提示顶点不存在  
         *   
         */  
        if (i < vertexNum && j < vertexNum && i >= 0 && j >= 0) {   
  
            if (i == j) {   
                return false;   
            }   
  
            /**  
             * 判断i的邻接结点集是否为空  
             */  
  
            if (table.get(i) == null) {   
               return false;
            }   
  
            /**  
             * 判断这条边是否存在,如果存在,则提示边已经存在  
             */  
            for (int q = 0; q < table.get(i).size(); q++) {   
  
                if (((Integer) table.get(i).get(q)).intValue() == j) {   
                 System.out.println("顶点" +i+"和"+"顶点"+j+ "这两点之间存在边");   
                    return true;     
                }   
            }   
        }   
        return false;   
    }   
  
    public void TopSort() {   //无前趋的顶点优先的拓扑排序方法
  
        for (int i = 0; i < vertexNum; i++)   //无前趋的顶点入栈
            if (in[i] == 0)   
                stack.push(i);   
        int k = 0;   
        while (!stack.isEmpty()) {
  
            result[k] = (Integer) stack.pop();   //弹出一个无前趋的顶点,并放入拓扑排序的结果集
  
            if (table.get(result[k]) != null) {  //这个顶点的邻接表非空 
                for (int j = 0; j < table.get(result[k]).size(); j++) {   
  
                    int temp = (Integer) table.get(result[k]).get(j);
                      //对result[k]每一个邻接点进行入度减1操作
                    if (--in[temp] == 0) { //如果temp的入度为0,进栈.
                        stack.push(temp);   
                    }     
                }    
            }   
            k++;     
        }   
  
        if (k < vertexNum) {   
            System.out.println("有回路");   
            System.exit(0);    
        }     
    }   
  
    public int[] getResult() {   
        return result;     
    }   
  
}  

测试:


import java.util.List;   
  
public class GraphTest {   
  
    public static  void main(String args[]){   
        Graph graph = new Graph(6);   
        graph.addEdge(1, 0);   
        graph.addEdge(2, 0);   
        graph.addEdge(3, 0);   
        graph.addEdge(1, 3);   
        graph.addEdge(2, 3);   
        graph.addEdge(3, 5);   
        graph.addEdge(4, 2);   
        graph.addEdge(4, 3);   
        graph.addEdge(4, 5);   
           
        graph.TopSort();   
        int[] list = graph.getResult();   
        System.out.println("拓扑排序的结果为:");   
        for(int i : list){                
            System.out.print(i+"        ");   
        }   
    }   
       
}  


运行:
C:\>java   GraphTest
拓扑排序的结果为:
4        2        1        3        5        0

下载源码
  • 大小: 1 KB
分享到:
评论

相关推荐

    操作系统 拓扑排序算法

    任意给定一个有向图,设计一个算法,对它进行拓扑排序。拓扑排序算法思想:a.在有向图中任选一个没有前趋的顶点输出;b.从图中删除该顶点和所有以它为...或者直到图中没有无前趋的顶点为止,此情形表明有向图中存在环。

    数据结构拓扑排序课程设计.docx

    解决拓扑排序的方法如下: (1)在有向图中选一个没有前驱的顶点且输出之。 (2)从图中删除该顶点和所有以它为尾的弧。 重复上述两步,直至全部顶点均已输出,或者当前图中不存在无前驱的顶点为止。后一种情况则...

    c++实现拓扑排序

    对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑...

    拓扑排序-课程设计(源码、课程设计说明书)

    题目内容:输出有向网的拓扑排序序列。 拓扑排序的基本思想为: 1)从有向图中选出一个无前驱的顶点输出; 2)将此顶点和以他为起点的弧删除; 3)重复1)2)直到不存在无前驱的顶点; 4)若此时输出的顶点数小于有...

    拓扑排序--课程表

    对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑...

    拓扑排序与关键路径(C++版)

    拓扑排序与关键路径,在日常生活中,一项大的工程可以看作是由若干个子工程(这些子工程称为“活动” )组成的集合,这些子工程(活动)之间必定存在一些先后关系,即某些子工程(活动)必须在其它一些子工程(活动...

    图(有向图)的拓扑排序

    图的拓扑排序(有向图),用一个矩阵存储,环境为VC6.0

    使用c语言写的拓扑排序

    使用c语言写的一个拓扑排序小程序,希望对大家的学习有用,包含有实验报告

    有向图若有环,输出环,否则,拓扑排序

    对于有向图,若发现它是有环的,那么输出它的环,否则,就输出它的拓扑排序

    aov网和拓扑排序PPT学习教案.pptx

    aov网和拓扑排序PPT学习教案.pptx

    数据结构_图的拓扑排序

    题目:图的存储结构及拓扑排序  从键盘或文件读入有向图的顶点信息和弧信息(输入格式自拟);  建立有向图的十字链表存储结构;  利用拓扑排序方法判断该图是否为有向无环图。

    拓扑排序及关键路径的求解

    对给定的AOV网判断网中是否存在环,检测的办法是对有向图构造其顶点的拓扑有序序列,若网中所有顶点都在它的拓扑有序序列中,则该AOV网中必定不存在环。在拓扑排序的基础上实现关键路径的的求解。

    数据结构图的遍历及拓扑排序

    图的遍历#include #include #define max 100 //定义节点... printf("此拓扑排序树无环\n"); else printf("此拓扑排序树有环\n"); printf(" \n非递归深度优先遍历结果为:"); fdgsmap(maps); printf("\n"); }

    用C语言写的拓扑排序1,使用栈操作

    对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若,v&gt; ∈E(G),则u在线性序列中出现在v之前。

    用C语言写的拓扑排序2,直接打印出顺序

    对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若,v&gt; ∈E(G),则u在线性序列中出现在v之前。

    拓扑排序实验报告.doc

    或者直到图中没有无前趋的顶点为止,此情形表明有向图中存在环。 设计分析: 为实现对无权值有向图进行拓扑排序,输出拓扑序列,先考虑如何存储这个有向图。拓 扑排序的过程中要求找到入度为0的顶点,所以要采用邻接...

    数据结构课程设计-输出DAG的所有拓扑排序序列-内容与要求.docx

    要求输出的拓扑排序结果用顶点序号或字母表示。输出结果需存于字符文件。输出结果中应显示全部拓扑排序序列的数目。如果DAG存在环(即拓扑排序失败),输出结果中应显示拓扑排序序列的数目为0。 课程设计报告要求给...

    逆邻接表快速实现拓扑排序

    逆邻接表实现拓扑排序,能够更快速直接的计算顶点的入度,即终点指向结点,有几个边表,则代表入度是几

    凸包顶点逆时针排序

    将凸包的顶点按逆时针的顺序排序,代码用java实现,已经亲测验证成功

Global site tag (gtag.js) - Google Analytics