C# 使用深度优先级遍历算法获取闭环

程序根据网上的例子(具体哪位老哥写的忘记了。。)修改,只修改了最后“获取堆栈当前顶部值的下一个连通点”的功能,在此处穿插了对闭环的判断,并输出

// 检查闭环情况
if (thestack.Contains(j) && thestack.Count > 2) {
    List stackValues = new List(thestack.ToArray());
    // 将堆栈转为list后,top的位置是0,所以应该从大向小遍历
    for (int i = stackValues.Count - 1; i > 1; i--) {
        if (stackValues[i].Equals(j)) {
            // 从当前i递减直到stackValues的top
            string res = "形成闭环:";
            for (int t = i; t >= 0; t--) {
                res += vertexList[(int) stackValues[t]] + ",";
            }

            Console.WriteLine(res);
            break;
        }
    }
}
 
 
using System;
using System.Collections;
using System.Collections.Generic;

namespace math
{
    class Program
    {
        static void Main(string[] args)
        {
            Graph graph = new Graph();
            graph.addVertex('A');
            graph.addVertex('B');
            graph.addVertex('C');
            graph.addVertex('D');
            graph.addVertex('E');
            graph.addVertex('F');
//            graph.addVertex('G');
//            graph.addVertex('H');
            graph.addEdge('A', 'B');
            graph.addEdge('B', 'C');
            graph.addEdge('C', 'A');
            graph.addEdge('A', 'D');
            graph.addEdge('D', 'E');
            graph.addEdge('E', 'F');
            graph.addEdge('F', 'D');
//            graph.addEdge('B', 'D');
//            graph.addEdge('B', 'E');
//            graph.addEdge('E', 'H');
//            graph.addEdge('D', 'H');
//            graph.addEdge('A', 'C');
//            graph.addEdge('C', 'F');
//            graph.addEdge('F', 'G');
//            graph.addEdge('C', 'G');
            Console.WriteLine("深度遍历寻找环结果:");
            graph.dfs();
            Console.WriteLine();
        }
    }

    class Vertex
    {
        public Vertex(char label)
        {
            _label = label;
            wasVisited = false;
        }

        public char _label;
        public bool wasVisited;

        public override string ToString()
        {
            return _label.ToString();
        }
    }

    class Graph
    {
        private static int flag = 1;
        private int max_vertexs = 20; //最大顶点数
        private Vertex[] vertexList;
        private int[,] adjMat;
        private int countVertexs;
        private Stack thestack;

        public Graph()
        {
            vertexList = new Vertex[max_vertexs];
            adjMat = new int[max_vertexs, max_vertexs];
            countVertexs = 0;
            for (int j = 0; j < max_vertexs; j++)
            for (int k = 0; k < max_vertexs; k++)
                adjMat[j, k] = 0;
            thestack = new Stack(max_vertexs);
        }

        //初始添加点数
        public void addVertex(char label)
        {
            vertexList[countVertexs++] = new Vertex(label);
        }

        public void addEdge(int start, int end)
        {
            adjMat[start, end] = 1;
            adjMat[end, start] = 1;
        }

        public void addEdge(char startV, char endV)
        {
            int start = -1, end = -1;
            for (int i = 0; i < countVertexs; i++) {
                if (startV == vertexList[i]._label) start = i;
                if (endV == vertexList[i]._label) end = i;
            }

            if (start == -1) Console.WriteLine("顶点{0}不存在", startV);
            if (end == -1) Console.WriteLine("顶点{0}不存在", endV);
            //权值默认为1 
            adjMat[start, end] = 1;
            adjMat[end, start] = 1;
        }

        //显示字符
        public void displayVertex(int v)
        {
//            if (flag == 1) {
//                Console.Write(vertexList[v]._label);
//            }
//            else {
//                Console.Write("," + vertexList[v]._label);
//            }
//
//            flag++;
        }

        //深度优先遍历
        public void dfs()
        {
            vertexList[0].wasVisited = true;
            displayVertex(0);
            thestack.Push(0);
            //遍历结点
            while (thestack.Count != 0) {
                //从第v个顶点出发递归地深度优先遍历图  (读取栈里的第一个元素,但是不出栈)
                int v = getAdjUnvisitedVertex(Int32.Parse(thestack.Peek().ToString()));
                if (v == -1)
                    //元素出栈
                    thestack.Pop();
                else {
                    vertexList[v].wasVisited = true;
                    displayVertex(v);
                    //元素进栈
                    thestack.Push(v);
                }
            }

            //初始化所有的顶点状态为未被访问
            for (int j = 0; j < countVertexs; j++)
                vertexList[j].wasVisited = false;
        }

        /**
         * 获得本vertex的下一个可访问的点
         * 此处可以做环检测
         * 如果要检测的下一帧存在在堆栈中,且不是top的上一个连接点,那么成立
         */
        public int getAdjUnvisitedVertex(int v)
        {
            for (int j = 0; j < countVertexs; j++) {
                if (adjMat[v, j] == 1) {
                    // 检查闭环情况
                    if (thestack.Contains(j) && thestack.Count > 2) {
                        List stackValues = new List(thestack.ToArray());
                        // 将堆栈转为list后,top的位置是0,所以应该从大向小遍历
                        for (int i = stackValues.Count - 1; i > 1; i--) {
                            if (stackValues[i].Equals(j)) {
                                // 从当前i递减直到stackValues的top
                                string res = "形成闭环:";
                                for (int t = i; t >= 0; t--) {
                                    res += vertexList[(int) stackValues[t]] + ",";
                                }

                                Console.WriteLine(res);
                                break;
                            }
                        }
                    }

                    if (vertexList[j].wasVisited == false) {
                        return j;
                    }
                }
            }

            return -1;
        }
    }
}
 
 
运行结果 - 图中例子存在两个闭环,此处已识别出来

你可能感兴趣的:(C# 使用深度优先级遍历算法获取闭环)