private void dfs(GraphDigraph g, int v) { // 将顶点v设置成已搜索 this.markeds[v] = true; // 把当前顶点进栈 this.onStack[v] = true; // 进行深度搜索 IEnumerator ie = g.adjGet(v).GetEnumerator(); while (ie.MoveNext()) { int w = (int)ie.Current; if (!this.markeds[w]) { dfs(g, w); } else { // 判断当前顶点是否已经在栈中, true表示是环, if (this.onStack[w]) { this.hasCycleBool = true; return; } } } // 把当前顶点出栈 this.onStack[v] = false; }
/// <summary> /// 构造拓扑排序对象 /// </summary> /// <param name="g">有向图</param> public TopoLogicalOrder(GraphDigraph g) { // 检测图是否有环 GraphDirectedCyle cycle = new GraphDirectedCyle(g); bool hasCycle = cycle.hasCycle(); if (!hasCycle) { DepthFirstOrder depth = new DepthFirstOrder(g); orderStack = depth.reversePost(); } }
/// <summary> /// 创建一个顶点排序对象 生成顶点线性队列 /// </summary> /// <param name="g"></param> public DepthFirstOrder(GraphDigraph g) { // 初始markeds 数组 this.markeds = new bool[g.countV()]; // 初始化 reversePost stack 栈 this.reversePostStack = new StackList <int>(); // 遍历图中的每一个顶点,让每一个定点做作为入口,完成一次深度优先搜索 for (int v = 0; v < g.countV(); v++) { if (!this.markeds[v]) { dfs(g, v); } } }
/// <summary> /// 基于深度优先搜索,生成顶点线性排序 /// </summary> /// <param name="g"></param> /// <param name="v"></param> private void dfs(GraphDigraph g, int v) { // 标记当前v已经被搜索 this.markeds[v] = true; // 通过循环深度搜索v IEnumerator ie = g.adjGet(v).GetEnumerator(); while (ie.MoveNext()) { int w = (int)ie.Current; if (!this.markeds[w]) { dfs(g, w); } } // 让当前这个顶点进栈 this.reversePostStack.push(v); }
private GraphDigraph reverse() { // 创建图 GraphDigraph g = new GraphDigraph(this.V); // 添加边, 遍历原图的每个顶点 for (int v = 0; v < this.V; v++) { // 获取由该顶点v指出的所有的边 IEnumerator ie = this.adj[v].GetEnumerator(); while (ie.MoveNext()) { // 原图中表示的是由顶点v->w的边 int w = (int)ie.Current; g.addEdge(w, v); } } return(g); }
public GraphDirectedCyle(GraphDigraph g) { // 初始化 markeds 数组 this.markeds = new bool[g.countV()]; // 初始化 hasCycleBool this.hasCycleBool = false; //初始化onStack this.onStack = new bool[g.countV()]; // 找到图中每一个顶点 让每一个顶点作为入口调用一次 dfs 函数 for (int v = 0; v < g.countV(); v++) { // 如果当前顶点 还没有搜索过 则调用dfs搜索 if (!this.markeds[v]) { dfs(g, v); } } }
/// <summary> /// 拓扑排序 测试 /// </summary> private static void TopoLogicalOrderTest() { // 准备有向图 GraphDigraph graph = new GraphDigraph(6); graph.addEdge(0, 2); graph.addEdge(0, 3); graph.addEdge(1, 3); graph.addEdge(2, 4); graph.addEdge(3, 4); graph.addEdge(4, 5); // 通过TopoLogicalOrder对象排序 TopoLogicalOrder order = new TopoLogicalOrder(graph); if (!order.isCycle()) { StackList <int> stack = order.order(); // 获取顶点线性排序的打印 if (stack != null) { IEnumerator ie = stack.GetEnumerator(); while (ie.MoveNext()) { int o = (int)ie.Current; Console.Write(o + ","); } } else { Console.WriteLine("TopoLogicalOrder stack is null."); } } else { Console.WriteLine("has cycle."); } }