无向图求所有路径
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