C军

不玩博客了!

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

无向图求所有路径

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp5
{
    class Program
    {


        static void Main(string[] args)
        {


            /* 定义节点关系 */
            int[][] nodeRalation = new int[][]
            {
                new int[]{1},      //0
                new int[]{0,5,2,3},//1
                new int[]{1,4},    //2
                new int[]{1,4},    //3
                new int[]{2,3,5},  //4
                new int[]{1,4}     //5
            };
        
            /* 定义节点数组 */
            Node[] node = new Node[nodeRalation.Length];
        
            for(int i=0;i < nodeRalation.Length; i++)
            {
                node[i] = new Node();
                node[i].Name = "node" + i;
            }
        
            /* 定义与节点相关联的节点集合 */
            for(int i=0;i<nodeRalation.Length; i++)
            {
                List<Node> List = new List<Node>();
            
                for(int j=0;j<nodeRalation[i].Length; j++)
                {
                    List.Add(node[nodeRalation[i][j]]);
                }
                node[i].RelationNodes = List;
                List = null;  //释放内存
            }
 
            /* 开始搜索所有路径 */
            GetPaths(node[0], null, node[0], node[4]);


            Console.ReadKey();






    }


    /* 临时保存路径节点的栈 */
    public static Stack<Node> stack = new Stack<Node>();
    /* 存储路径的集合 */
    public static List<Object[]> sers = new List<Object[]>();

    /* 判断节点是否在栈中 */
    public static bool IsNodeInStack(Node node)
    {
        List<Node> it = stack.ToList();
        foreach(Node item in it)
        {
            if (node == item)
            {
                return true;
            }
        }
        return false;
    }

    /* 此时栈中的节点组成一条所求路径,转储并打印输出 */
    public static void ShowAndSavePath()
    {
        Object[] o = stack.ToArray();
        for (int i = 0; i < o.Length; i++)
        {
            Node nNode = (Node)o[i];

            if (i < (o.Length - 1))
            {
                Console.WriteLine(nNode.Name + "->");
            }
            else
            {
                Console.WriteLine(nNode.Name);
            }
                        
        }
        //转储
        sers.Add(o); 
        {
            Console.WriteLine("\n");
        }
    }

    /*
     * 寻找路径的方法 
     * cNode: 当前的起始节点currentNode
     * pNode: 当前起始节点的上一节点previousNode
     * sNode: 最初的起始节点startNode
     * eNode: 终点endNode
     */
    public static bool GetPaths(Node cNode, Node pNode, Node sNode, Node eNode)
    {
        Node nNode = null;
        /* 如果符合条件判断说明出现环路,不能再顺着该路径继续寻路,返回false */
        if (cNode != null && pNode != null && cNode == pNode)
        {
            return false;
        }
            

        if (cNode != null)
        {
            int i = 0;
            /* 起始节点入栈 */
            stack.Push(cNode);
            /* 如果该起始节点就是终点,说明找到一条路径 */
            if (cNode == eNode)
            {
                /* 转储并打印输出该路径,返回true */
                ShowAndSavePath();
                return true;
            }
            /* 如果不是,继续寻路 */
            else
            {
                /* 
                 * 从与当前起始节点cNode有连接关系的节点集中按顺序遍历得到一个节点
                 * 作为下一次递归寻路时的起始节点 
                 */
                nNode = cNode.RelationNodes[i];
                while (nNode != null)
                {
                    /*
                     * 如果nNode是最初的起始节点或者nNode就是cNode的上一节点或者nNode已经在栈中 , 
                     * 说明产生环路 ,应重新在与当前起始节点有连接关系的节点集中寻找nNode
                     */
                    if (pNode != null && (nNode == sNode || nNode == pNode || IsNodeInStack(nNode)))
                    {
                        i++;
                        if (i >= cNode.RelationNodes.Count())
                        {
                            nNode = null;
                        }
                        else
                        {
                            nNode = cNode.RelationNodes[i];
                        }
                        continue;
                    }
                    /* 以nNode为新的起始节点,当前起始节点cNode为上一节点,递归调用寻路方法 */
                    if (GetPaths(nNode, cNode, sNode, eNode))/* 递归调用 */
                    {
                        /* 如果找到一条路径,则弹出栈顶节点 */
                        stack.Pop();
                    }
                    /* 继续在与cNode有连接关系的节点集中测试nNode */
                    i++;
                    if (i >= cNode.RelationNodes.Count())
                    {
                        nNode = null;
                    }
                    else
                    {
                        nNode = cNode.RelationNodes[i];
                    }
                }
                /* 
                 * 当遍历完所有与cNode有连接关系的节点后,
                 * 说明在以cNode为起始节点到终点的路径已经全部找到 
                 */
                stack.Pop();
                return false;
            }
        }
        else
        {
            return false;
        }
    }

    }



    /// <summary>
    /// 表示一个节点以及和这个节点相连的所有节点
    /// </summary>
    public class Node
    {
        public String Name
        {
            get;
            set;
        }

        public List<Node> RelationNodes
        {
            get;
            set;
        }
    }




}

参考:https://blog.csdn.net/hcx25909/article/details/8043107

posted on 2021-07-14 10:14  逆心  阅读(211)  评论(0编辑  收藏  举报