【问题标题】:Searching a tree and outputting the path to that node in C++在 C++ 中搜索树并输出该节点的路径
【发布时间】:2011-12-19 02:10:07
【问题描述】:

假设我们有以下结构:

struct ATree {
  string id;
  int numof_children;
  ATree *children[5];
};

我如何能够搜索一个 id 并输出该 id 的路径?我有办法找出 id 是否在树中,但输出正确的路径是另一回事。我曾尝试使用字符串流,但它似乎无法正常工作(我得到的路径包含不通向我想要的 id 的 id)。注意:假设 id 在树中只能出现一次

这应该使用递归来完成吗?还是可以使用循环来完成?

【问题讨论】:

  • 任何递归都可以用循环重写。
  • 我建议将访问过的节点存储在std::vectorstd::list 中,这就是您下到节点的路径。
  • @littleadv:这是一个比我以前听过的更有力的说法,如果不在其他地方实现堆栈,我认为它是不正确的。
  • @MooingDuck - 计算 101,任何递归解决方案都可以重写为迭代。这是从基本图灵机的等价性得出的。当然,您还需要一些变量。
  • @littleadv:正确,但在许多情况下,迭代必须创建一个堆栈。在这种情况下(如果不考虑 stackoverflow),使用递归通常更简单。

标签: c++ search path tree


【解决方案1】:

对于您要经过的每个节点,您基本上应该将您到达的节点保留为当前节点。然后在找到正确路径后将它们弹出并打印出来。

如果您将它们保存在 std::stack 结构中,那么当您在到达树叶后返回并且找不到所需的 id 时,很容易将它们弹出。

如果您以递归方式执行此操作,那么您只需要调用堆栈就足够了,如果您将它们转换为循环(迭代地),那么您需要 std::stack 来记住状态,但这相当简单,真的。

【讨论】:

  • 我不能使用堆栈。替代方案?
  • @DillPixel - 那么也许你应该列出你的所有限制,而不是等待解决方案然后说你不允许使用这个或那个?
  • 使用我的解决方案,它不使用堆栈:)
  • @hochi,它确实......它是递归的。
  • 好的,它不使用std::stack。我认为这很清楚,因为递归通常使用堆栈。当然你可以优化尾递归等,但参考一般情况。
【解决方案2】:

算法的大致轮廓:

std::vector< const ATree* >
getPath(const ATree* tree, const std::string& id)
{
        std::vector< const ATree* > path;

        if (tree->id == id) {
                path.push_back(tree);
        } else {
                for (int i=0; i < tree->numof_children; i++) {
                        std::vector< const ATree* > tmp=
                                getPath(tree->children[i], id);
                        if (tmp.size() > 0) {
                            path.push_back(tree);
                            path.insert(path.end(), tmp.begin(), tmp.end());
                                break;
                        }
                }
        }

        return path;
}

【讨论】:

  • 现在好多了。 OP 说他不能使用std::stack,我猜std::vector 也是如此,但我认为我们可以让他弄清楚如何更改为允许使用的内容。
  • 我误读了要求,它只是一个粗略的大纲。现在这段代码可以工作了,我写了一个小树创建和搜索示例来验证。
【解决方案3】:

我相信以下代码可以让您了解应该做什么(递归):

bool find(const string& i_id, const ATree* i_tree, string& o_path) {
  if(!i_tree) return false;
  if (i_id == i_tree->id) {
    o_path = i_tree->id;
    return true;
  }
  string path;
  for (size_t i = 0; i < i_tree->numof_children; ++i) {
    if (find(id, i_tree->children[i], path)) {
      o_path = i_tree->id + '/' + path;
      return true;
    }
  }
  return false;
}

【讨论】:

  • 您好,为什么代码在 if (i_id == i_tree->id) 中返回 false,或者这是一个错误?这听起来也很愚蠢,但是我在哪里输出路径(到标准输出)?如果说 id 在树的第三层,我认为它应该去的位置不起作用...
  • Nvm,我用你的想法+字符串流让它工作了。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-02
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 1970-01-01
  • 2016-08-16
  • 2018-07-07
相关资源
最近更新 更多