Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #6
0
 /// <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);
 }
Beispiel #7
0
 /// <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);
     }
 }
Beispiel #8
0
 /// <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);
        }
Beispiel #10
0
        /// <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);
        }