【问题标题】:Binary Search Tree Traversal - PreOrder二叉搜索树遍历 - PreOrder
【发布时间】:2011-09-08 05:25:32
【问题描述】:

我正在尝试使用返回 IEnumerable 的 yield return 来实现 Tree Traversal PreOrder

private IEnumerable<T> Preorder(Node<T> node)
{

    while(node != null)
    {
        yield return node.Data;
        yield return node.LeftChild.Data;
        yield return node.RightChild.Data;
    }

}

在这种情况下,它进入无限循环,是的,我知道我需要继续遍历。如何做到这一点?

如果 LeftChild 或 RightChild 为 null,则抛出 null 异常。我认为那时我需要让步;

我想,inorder 和 postorder 也很相似,有什么想法吗?

我有 Resursive 版本,效果很好。

public void PreOrderTraversal(Node<T> node)
{

    if(node!=null)
    {
        Console.Write(node.Data);
    }
    if (node.LeftChild != null)
    {
        PreOrderTraversal(node.LeftChild);
    }

    if (node.RightChild != null)
    {
        PreOrderTraversal(node.RightChild);
    }
}

谢谢。

【问题讨论】:

    标签: c# .net algorithm tree binary-search-tree


    【解决方案1】:

    选项 #1 递归

    public class Node<T> : IEnumerable<T>
    {
        public Node<T> LeftChild { get; set; }
    
        public Node<T> RightChild { get; set; }
    
        public T Data { get; set; }
    
        public IEnumerator<T> GetEnumerator()
        {
            yield return Data;
    
            if (LeftChild != null)
            {
                foreach (var child in LeftChild)
                    yield return child;
            }
            if (RightChild != null)
            {
                foreach (var child in RightChild)
                    yield return child;
            }
        }
    
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
    

    用法:

    var child1 = new Node<int> { Data = 1 };
    var child2 = new Node<int> { Data = 2 };
    var child3 = new Node<int> { Data = 3, LeftChild = child1 };
    var root = new Node<int> { Data = 4, LeftChild = child3, RightChild = child2 };
    
    foreach (var value in root)
        Console.WriteLine(value);
    

    选项 #2 非递归静态方法

    public static IEnumerable<T> Preorder<T>(Node<T> root)
    {
        var stack = new Stack<Node<T>>();
        stack.Push(root);
    
        while (stack.Count > 0)
        {
            var node = stack.Pop();
            yield return node.Data;
            if (node.RightChild != null)
                stack.Push(node.RightChild);
            if (node.LeftChild != null)
                stack.Push(node.LeftChild);
        }
    }
    

    【讨论】:

    • 这将停在孩子们身上,无需进一步遍历。
    • @user177883 - 您最初的问题没有提到递归选项是不可接受的。我用非递归方法更新了答案。
    • +1,@Alex:您说得对,先生,我很抱歉。我没有完全复制/粘贴你的(我现在要在午夜停止编码)。
    • 请注意,如果使用堆栈,您应该将右孩子推到左孩子之前,以确保前序遍历。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多