/// <summary> /// 层序遍历 /// 广度优先的思想 /// </summary> /// <returns></returns> public QueueList <TKey> layerErgodic() { // 定义两个队列, 分别存储树中的键,和树中的节点 QueueList <Node> nodes = new QueueList <Node>(); QueueList <TKey> keys = new QueueList <TKey>(); // 默认往队列中放入根节点 nodes.enqueue(this.root); while (!nodes.isEmpty()) { // 从 nodes队列中弹出节点,把键放到keys中 Node n = nodes.dequeue(); keys.enqueue(n.key); // 判断当前节点有没有左子节点, 有:放入nodes中 if (n.left != null) { nodes.enqueue(n.left); } // 判断当前节点有没有右子节点,有:放入nodes中 if (n.right != null) { nodes.enqueue(n.right); } } return(keys); }
/// <summary> /// 队列 测试 /// </summary> private static void QueueListTest() { // 创建队列对象 QueueList <Student> list = new QueueList <Student>(); // 测试队列的enqueue方法 for (int i = 0; i < 5; i++) { list.enqueue(new Student() { cardID = i, name = "sun" + i }); } Student stu = list.dequeue(); Console.WriteLine("Result: " + stu.cardID); Console.WriteLine(); IEnumerator ie = list.GetEnumerator(); while (ie.MoveNext()) { if (ie.Current is Student) { Student s = ie.Current as Student; Console.WriteLine("cardID: " + s.cardID); } else { Console.WriteLine("QueueList GetEnumerator is null."); } } }
/// <summary> /// 折纸问题 /// </summary> private static void PagerFolderTest() { // 模拟折纸 生成树 int count = 3; // 定义根节点 Node <string> root = null; for (int i = 0; i < count; i++) { if (i == 0) { root = new Node <string>("down", null, null); continue; } // 当前不是第一次对折 // 定义一个辅助队列, 通过层序遍历的思想,找到叶子节点,叶子节点添加子节点 QueueList <Node <string> > queue = new QueueList <Node <string> >(); queue.enqueue(root); while (!queue.isEmpty()) { // 从队列中弹出一个节点 Node <string> temp = queue.dequeue(); // 如果有左子节点 或 右子节点,把子节点放到队列中 if (temp.left != null) { queue.enqueue(temp.left); } if (temp.right != null) { queue.enqueue(temp.right); } // 如果没有子节点, 则需要该节点添加左子节点和右子节点 if (temp.left == null && temp.right == null) { temp.left = new Node <string>("down", null, null); temp.right = new Node <string>("up", null, null); } } } // create root tree // 遍历树 (中序遍历) 打印每个节点 printTree(root); }
/// <summary> /// 获取最小生成树的所有边 /// </summary> /// <returns></returns> public QueueList <Edge> edges() { // 创建队列对象 QueueList <Edge> allEdges = new QueueList <Edge>(); // 遍历 edgeTo数组,拿到每一条边,如果不为null,则添加到队列中 for (int i = 0; i < this.edgeTo.Length; i++) { if (this.edgeTo[i] != null) { allEdges.enqueue(this.edgeTo[i]); } } return(allEdges); }
/// <summary> /// 获取加权有向图的所有边 /// </summary> /// <returns></returns> public QueueList <EdgeDirected> edges() { // 遍历图中的每一个顶点,得到该顶点的邻阶表遍历得到每一条边,添加到队列中返回即可 QueueList <EdgeDirected> allEdges = new QueueList <EdgeDirected>(); for (int v = 0; v < this.V; v++) { IEnumerator ie = this.adjQueue[v].GetEnumerator(); while (ie.MoveNext()) { EdgeDirected e = (EdgeDirected)ie.Current; allEdges.enqueue(e); } } return(allEdges); }
/// <summary> /// 使用后序遍历 把指定树x中的键放到 keys中 /// 深度优先的思想 /// </summary> private void afterErgodic(Node x, QueueList <TKey> keys) { if (x == null) { return; } // 递归 先把左子树的键放到keys中 if (x.left != null) { afterErgodic(x.left, keys); } // 递归 把右子树的键放到keys中 if (x.right != null) { afterErgodic(x.right, keys); } // 把 x 节点的键放到keys中 keys.enqueue(x.key); }
/// <summary> /// 使用中序遍历 获取指定树x中的所有键,放到keys中 /// </summary> /// <param name="x"></param> /// <param name="keys"></param> private void midErgodic(Node x, QueueList <TKey> keys) { if (x == null) { return; } // 先递归 把左子树的键放到 keys中 if (x.left != null) { midErgodic(x.left, keys); } // 在把根节点的键放到 keys中 keys.enqueue(x.key); // 递归把右子键放到keys中 if (x.right != null) { midErgodic(x.right, keys); } }
/// <summary> /// 获取指定节点的所有键 /// </summary> /// <param name="x"></param> /// <param name="keys"></param> private void preErgodic(Node x, QueueList <TKey> keys) { if (x == null) { return; } // 把x节点的key放到keys中 keys.enqueue(x.key); // 递归调用遍历x节点的左子树 if (x.left != null) { preErgodic(x.left, keys); } // 递归遍历x节点的右子树 if (x.right != null) { preErgodic(x.right, keys); } }
/// <summary> /// 获取加权无向图所有的边 /// </summary> /// <returns></returns> public QueueList <Edge> edges() { // 创建队列存储所有的边 QueueList <Edge> allEdge = new QueueList <Edge>(); //遍历图中的每一个边,找到该顶点的邻接表,邻接表中存储了该顶点关联的每一条边 for (int v = 0; v < this.countV(); v++) { // 遍历v顶点的邻接表,找到每一条和v关联的边 IEnumerator ie = this.adj(v).GetEnumerator(); while (ie.MoveNext()) { Edge e = (Edge)ie.Current; if (e.other(v) < v) { // 因为是无向图,所以同一条边会同时出现在了它关联的两个顶点的邻接表,需要让一条边只记录一次 allEdge.enqueue(e); } } } return(allEdge); }
/// <summary> /// 查询从起点s到顶点v的最短路径中所有的边 /// </summary> /// <param name="v"></param> /// <returns></returns> public QueueList <EdgeDirected> pathTo(int v) { // 判断从顶点 s 到顶点v是否可达 if (!this.hasPathTo(v)) { return(null); } // 创建队列对象 QueueList <EdgeDirected> allEdges = new QueueList <EdgeDirected>(); while (true) { EdgeDirected e = this.edgeTo[v]; if (e == null) { break; } allEdges.enqueue(e); v = e.from(); } return(allEdges); }