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

无前趋的顶点优先的拓扑排序方法(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
分享到:
评论

相关推荐

    拓扑排序java实现

    ### 拓扑排序Java实现知识点详解 #### 一、拓扑排序概念 拓扑排序是一种针对有向无环图(DAG)进行排序的方法,主要用于确定任务执行的顺序。在实际应用中,例如项目管理中的任务调度、依赖关系解析等场景下非常...

    本周算法图的拓扑排序Java开发Java经验技巧共6页.p

    对于给定的"本周算法图的拓扑排序Java开发Java经验技巧共6页.pdf.zip"文件,很可能是包含了一篇关于拓扑排序在Java编程实践中的详细教程或指南,内容可能包括理论解释、代码示例、常见问题以及优化技巧。通过阅读这...

    数据结构拓扑排序课程设计报告

    数据结构中的拓扑排序是一种对有向无环图(DAG)进行排序的方法,使得所有有向边都从排序序列中的较前位置指向较后位置。在这个课程设计中,使用Java语言实现了拓扑排序算法。 拓扑排序的目标是将DAG的顶点排成线性...

    数据结构拓扑排序图形化界面实现

    拓扑排序是对有向无环图的顶点进行线性排序的一种方式,使得对于图中的每一条有向边 (u, v),顶点 u 的排序位置都位于顶点 v 之前。换句话说,如果存在一条从节点 A 到节点 B 的路径,那么在拓扑排序的结果中,A ...

    【数据结构】基于紧缩图的邻接表的拓扑排序正文终稿.doc

    拓扑排序是一种对有向无环图(DAG,Directed Acyclic Graph)进行线性排序的方法,使得对于图中的每一条有向边uv,都有u出现在排序结果的前面。 紧缩图的邻接表是一种优化的图存储结构,它将原邻接表中每个顶点的...

    拓扑序列的演示

    拓扑排序是对有向无环图的顶点的一种线性排序,使得对于图中的每条有向边 (u, v),顶点 u 在排序结果中都出现在顶点 v 之前。如果存在多种满足条件的排序,那么所有这些排序都是正确的。 在实际应用中,拓扑排序...

    Java实现图的深度优先遍历和广度优先遍历

    DFS适合查找路径或进行拓扑排序,而BFS则更适合寻找最短路径或检查连通性。在Java中,通过适当的递归或迭代算法结合数据结构(如栈或队列),我们可以有效地实现这两种遍历方法,从而在各种图形应用中解决问题。

    优先队列算法实现(Java)

    - 拓扑排序:在有向无环图中,优先队列可以用来找到入度为零的顶点并按顺序处理它们。 - Dijkstra最短路径算法:用于找到图中两个节点之间的最短路径,每次从优先队列中取出距离源点最近的节点进行扩展。 - ...

    Java版查找并打印有向图中的所有环路径

    另一方面,拓扑排序是将有向无环图(DAG)的顶点线性排列的一种方式,如果存在环,则无法进行拓扑排序,因此可以借此判断图中是否有环。 在`Graph.java`中,可能会有一个名为`detectCycle`的函数,它使用DFS进行...

    java深度优先遍历

    - 拓扑排序:在有向无环图(DAG)中,DFS可以用于拓扑排序,确定节点的顺序。 5. **代码示例**: 在Java中,使用递归实现二叉树的DFS遍历(前序、中序、后序)如下: ```java class TreeNode { int val; ...

    java编写的图的各种操作

    拓扑排序是对于有向无环图(DAG)的操作,它返回一个线性的顶点序列,使得对于每条有向边 (u, v),顶点u都在顶点v之前。Kahn算法是一种常见的拓扑排序实现,它通过选择入度为零的顶点并移除,然后更新其他顶点的入度...

    深度优先搜索输出有向图中的所有环(JAVA)

    在实际应用中,DFS寻找环的算法广泛应用于各种场景,如检测图的连通性、解决拓扑排序问题、查找图的强连通分量等。了解并熟练掌握这种算法对于IT从业者来说是非常重要的,因为它可以帮助解决很多实际问题,例如在...

    深度优先搜索学习五例之一(JAVA)

    3. **拓扑排序**:在有向无环图(DAG)中,DFS可以用来进行拓扑排序,将所有节点按照没有前驱的顺序排列。 4. **迷宫求解**:DFS也可以应用于二维数组表示的迷宫问题,从起点开始,不断尝试所有可能的路径,直到找到...

    topsort:拓扑排序的实现

    在Java中,我们可以采用两种主要方法来实现拓扑排序:深度优先搜索(DFS)和广度优先搜索(BFS)。接下来,我们将详细讨论这两种方法。 1. 深度优先搜索(DFS)实现: DFS是一种递归的搜索策略,它首先访问一个节点...

    JAVA求矩阵表示的有向图的强连通分支

    2. **构建拓扑排序**:利用拓扑排序,我们可以将无向图的顶点按照入度(指向该顶点的边数)排序。对于强连通分量,其所有顶点的入度和出度都是相同的。 3. **判断强连通性**:遍历排序后的顶点,如果发现一个顶点的...

    Java经典算法教程:深度优先搜索(DFS)算法

    理解并掌握DFS算法对于解决计算机科学中的许多问题至关重要,包括图的遍历、最短路径问题、拓扑排序等。 通过深入学习DFS,Java开发者可以更好地处理与图和树相关的复杂问题,提升编程能力和算法理解。此外,掌握...

    java数据结构

    有向无环图(DAG)常用于表示事件的先后关系,如拓扑排序和关键路径。 查找是指在一个数据集合中查找满足某些条件的数据元素。顺序查找是最简单的一种查找方法,折半查找则是基于有序数组的高效查找方法。查找树如...

    2021年西藏自治区JAVA最新版本大纲2021年西藏自治区JAVA最新版本大纲.docx

    拓扑排序是对有向无环图(DAG,Directed Acyclic Graph)的顶点的一种线性排序,其中对于每条有向边 `(u, v)`,顶点 `u` 总是出现在顶点 `v` 之前。给定的有向图 G 可以通过深度优先搜索(DFS)或广度优先搜索(BFS...

Global site tag (gtag.js) - Google Analytics