C# 递归创建数学表达式二叉树
下午好, 我在C#中实现了一个简单的二叉树,我打算用它递归地创建数学表达式树。但是我遇到了一些问题,因为我已经多年没有做递归调用了,我正在努力让大家了解为什么下面的内容只适用于深度为2的二叉树,而不适用于任何更深入的树 当然,如果递归是正确的,它应该能够构造深度为n的树。代码如下: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
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);
}