Recursion 递归方法:单个元素参数还是元素集合?

Recursion 递归方法:单个元素参数还是元素集合?,recursion,Recursion,我有一个关于实现递归方法的两种不同方法的优点的问题。我一直遵循版本1的方法,即接受单个节点参数,但我最近遇到了版本2中使用的样式,它接受节点集合 考虑以下节点类,以及访问方法的两个版本: class Node { public List<Node> children = new List<Node>(); // other data members } 版本2接受一组节点: Visit(List<Node> nodes) { forea

我有一个关于实现递归方法的两种不同方法的优点的问题。我一直遵循版本1的方法,即接受单个节点参数,但我最近遇到了版本2中使用的样式,它接受节点集合

考虑以下节点类,以及访问方法的两个版本:

class Node
{
    public List<Node> children = new List<Node>();
    // other data members 
}
版本2接受一组节点:

Visit(List<Node> nodes)
{
  foreach (Node n in nodes)
  {
    DoSomethingUsefulWith(n);
    Visit(n.children);
  }
}

使用一种形式比使用另一种形式有什么好处,哪怕是在风格上?即使在任何情况下使用任何一种方法版本都很简单,但选择是否仅基于您是从一个节点还是从一个节点集合开始?

您应该在递归函数中传递尽可能少的参数,即使是与您使用的类型专用的内存大小有关。这是我遵循的一般规则。如果你通过一些大的结构,你可能会耗尽内存。但是,如果您使用的是引用类型,则这不是问题。

您应该在递归函数中传递尽可能少的参数,即使这些参数与您使用的类型专用的内存大小有关。这是我遵循的一般规则。如果你通过一些大的结构,你可能会耗尽内存。但是,如果您使用的是引用类型,这不是问题。

我能看到的唯一显著区别是调用的方便性

这个第三版怎么样:

void Visit(Node n)
{
    DoSomethingUsefulWith(n);
    Visit(n.children);
}

void Visit(List<Node> nodes)
{
    foreach (Node n in nodes)
        Visit(n);
}

我能看到的唯一显著区别是通话的方便性

这个第三版怎么样:

void Visit(Node n)
{
    DoSomethingUsefulWith(n);
    Visit(n.children);
}

void Visit(List<Node> nodes)
{
    foreach (Node n in nodes)
        Visit(n);
}

从风格上讲,它取决于递归对象类型的根


实际上,它们是相同的。除非我的大脑正常

从风格上讲,它取决于递归对象类型的根


实际上,它们是相同的。除非我的大脑正常

我不会实现版本2,总是版本1。 在for-each循环中,版本2基本上是版本1

如果以后决定使用一个参数调用该方法,则始终可以重复使用版本1。 如果只有版本2和一个节点,则必须创建虚拟列表才能使用版本1

我不认为性能在这里是一个真正的问题。两个方法都有一个by-reference参数,它们应该使用大约相同的内存量


但是.NET可能能够更好地优化其中一个。请务必分析这两种方法。

我不会实现版本2,始终是版本1。 在for-each循环中,版本2基本上是版本1

如果以后决定使用一个参数调用该方法,则始终可以重复使用版本1。 如果只有版本2和一个节点,则必须创建虚拟列表才能使用版本1

我不认为性能在这里是一个真正的问题。两个方法都有一个by-reference参数,它们应该使用大约相同的内存量


但是.NET可能能够更好地优化其中一个。请务必分析这两种方法。

我认为版本2没有真正的好处,只是它限制了函数的灵活性,因为您不能再使用单个节点启动递归


在我看来,第1版更容易阅读,所以我会选择第1版。

我认为第2版没有真正的好处,只是它限制了函数的灵活性,因为你不能再用一个节点开始递归了


依我看,第1版更容易阅读,所以我会选择数字I。

我更喜欢采用单个节点的签名,因为如果我只想在该节点及其子节点上执行操作,我不必构建人工列表。在节点列表上使用它就像在列表上迭代并将其应用于每个节点一样简单。

我更喜欢采用单个节点的签名,因为如果我只想在该节点及其子节点上执行操作,那么我不必构建人工列表。在一个节点列表上使用它就像在列表上迭代并将其应用于每个节点一样简单。

我个人认为版本1更好地反映了通常基于单个节点的树的递归定义。因此,我倾向于版本1。

我个人认为版本1更好地反映了通常基于单个节点的树的递归定义。因此,我倾向于版本1。

如果我发现自己在第一个方法之外的代码中做了很多,我只会写第二个,否则我只会把迭代留在第一个。如果我发现自己在第一个方法之外的代码中做了很多,我只会写第二个,否则我只会把迭代留在第一个。