C# 递归创建数学表达式二叉树

C# 递归创建数学表达式二叉树,c#,parsing,data-structures,recursion,C#,Parsing,Data Structures,Recursion,下午好, 我在C#中实现了一个简单的二叉树,我打算用它递归地创建数学表达式树。但是我遇到了一些问题,因为我已经多年没有做递归调用了,我正在努力让大家了解为什么下面的内容只适用于深度为2的二叉树,而不适用于任何更深入的树 当然,如果递归是正确的,它应该能够构造深度为n的树。代码如下: Node<T> f; Node<T> t; Node<T> subRoot; Node<T> root; ////Only works with trees of d

下午好,

我在C#中实现了一个简单的二叉树,我打算用它递归地创建数学表达式树。但是我遇到了一些问题,因为我已经多年没有做递归调用了,我正在努力让大家了解为什么下面的内容只适用于深度为2的二叉树,而不适用于任何更深入的树

当然,如果递归是正确的,它应该能够构造深度为n的树。代码如下:

Node<T> f;
Node<T> t;
Node<T> subRoot;
Node<T> root;

////Only works with trees of depth 2.

private Node<T> Tree(List<T> prefixBank, int maxDepth)
{
    if (prefixBank.Count != 0)
    {
        if (maxDepth == 0)
        {
            t = new Node<T>(prefixBank[0]);
            subRoot.Add(t);

            prefixBank.Remove(prefixBank[0]);
        }
        else
        {
            if (root == null)
            {
                root = new Node<T>(prefixBank[0]);
                prefixBank.Remove(prefixBank[0]);
                Tree(prefixBank, maxDepth - 1);
            }

            f = new Node<T>(prefixBank[0]);

            if (isOperator(f))
            {
                root.Add(f);
                prefixBank.Remove(prefixBank[0]);
                subRoot = f;
            }

            for (int i = 0; i < 2; i++)
            {
                Tree(prefixBank, maxDepth - 1);
            }
        }
    }
return f;
}
我试图用生成字符串的相同方法创建树,但无法以任何常识的方式使其工作。我使用的是稍微修改过的版本。我对它进行了修改,使其具有一个add函数,可以自动添加到左子树或右子树,这样我就不必像本例那样指定Root.left.left.left等来创建树


如果有人能帮我纠正我的递归树创建代码,使其适用于n深度的树,我将非常感激。我对C#比较陌生,所以如果上面的内容有点粗略,我很抱歉

在进行这样的递归调用时,不应该依赖全局变量(一般来说,变量的范围应该尽可能窄,似乎没有任何理由将
f
t
作为类级变量)。您的代码对我来说没有多大意义,但我想主要的问题是您将每个节点直接添加到根中。我会这样做:

public Node<T> Tree(Queue<T> prefixBank)
{
    var node = new Node<T>(prefixBank.Dequeue());

    if (isOperator(node))
    {
        for (int i = 0; i < 2; i++)
        {
            node.Add(Tree(prefixBank));
        }
    }

    return node;
}

与您的问题无关,但您应该使用
StringBuilder
,而不是按您的方式连接字符串。此外,使用
List
这种方式效率非常低。如果您有一些空闲时间,这是一个挑战:假设(1)您不希望通过取消输入对象的队列来破坏输入对象,(2)节点是不可变的。你可以怎样修改你的算法?这很有效。在这里学到了宝贵的一课,谢谢@svick。在您看来,同时生成节点并将其添加到树中是否更好。而不是将它们存储在队列中的中间阶段。我正确地假设这也可以递归地完成???是的,我认为最好不用额外的步骤<代码>节点生成(int级别){返回级别==0?新节点(generatePerand(),新节点[0]):新节点(generatePerator(),新[]{生成(级别1),生成(级别1)};}
public Node<T> Tree(Queue<T> prefixBank)
{
    var node = new Node<T>(prefixBank.Dequeue());

    if (isOperator(node))
    {
        for (int i = 0; i < 2; i++)
        {
            node.Add(Tree(prefixBank));
        }
    }

    return node;
}
public Node<T> Tree(IEnumerable<T> prefixBank)
{
    return Tree(prefixBank.GetEnumerator());
}

public Node<T> Tree(IEnumerator<T> enumerator)
{
    enumerator.MoveNext();
    var value = enumerator.Current;

    var children = new List<Node<T>>(2);

    if (isOperator(value))
    {
        for (int i = 0; i < 2; i++)
        {
            children.Add(Tree(enumerator));
        }
    }

    return new Node<T>(value, children);
}