【问题标题】:I am totally stuck when dealing with N-ary Trees traversal在处理 N-ary Trees 遍历时我完全被卡住了
【发布时间】:2011-10-29 23:05:20
【问题描述】:

事情就是这样。我想遍历我的 N 叉树(在本例中为家谱)中的任意两个节点。下面是从根遍历到任意节点的情况的简化代码:

#include <iostream>
#include <string>
using namespace std;

const int max=100;

//structure definition
//every children has only one parent
struct Tree {
   string name;
   int numChildren;
   Tree *children[max];
   ~Tree(){delete [] children;}
}; 

//Label the nodes that are supposed to be in the path
//Suppose the names of those nodes do not contain whitespaces,just trivial names
int *travel_point(Tree *tree,string s){
    Tree *node = new Tree;
    Tree *temp = new Tree;
    node = tree;

    int a[100],i=0,j;
    for(j=0;j<100;j++) a[j]=-1;
    while(tree){
        if(tree->name == s){
           a[i]=0;
           break;
        }
        else{
           for(j=0;j<node->numChildren;j++){
              if(travel_point(node->children[j],s)!=NULL){
                break;      
                }
              }
           a[i]=j+1;
           i++;
           temp=node->children[j];
           node=temp;
        }
    }
    if(a[i-1]==-1) return NULL;
    else a;
}

这大致是我一直在做的。由于每个孩子只有一个父母,所以从根到任意一个节点的路径也是唯一的。所以我想将所有其他路径设置为 NULL,以防万一递归期间的优势。

我知道递归不是一个好主意,但我只是想试一试。

【问题讨论】:

  • 我不明白算法应该做什么,你能解释一下吗? travel_point 做什么以及 travel_point 返回什么?
  • 你的成员children不是new[]分配的数组,你不能delete[]它。
  • @chill 我试图设置一个析构函数,以便我可以递归地删除每个 Tree 类型结构的东西。那么正确的方法应该是什么?
  • @SalvatorePreviti travel_point 查找节点是否在我一直在寻找的路径上并返回 NULL 或指向存储标签的数组的指针。标签是子数组的索引。然后我将能够按索引遍历路径。
  • 哪条路径?你的意思是要查找包含指定名称的节点的路径,将路径表示为整数序列?在这种情况下,这个函数是完全错误的:/

标签: c++ algorithm


【解决方案1】:

好的,我不想解决你的作业,但我想给你一些建议。 首先,带有树的递归函数通常很好,通常树的高度不会太深,所以递归函数很好。它们更易于编写和理解。

1) 你不能在堆栈内存中返回一个指向数组的指针并假装它可以工作:)

2) 你需要一个堆栈类,使用std::stack&lt;int&gt;,将一个非常量引用作为参数传递给它,这样你就可以在你的所有函数中修改它,并返回一个布尔值,表明你是否找到了节点或不是。然后,您可以将堆栈转换为向量或数组,但正如我想象的算法,您需要一个堆栈数据结构。

3) 不需要通过复制传递字符串,传递一个 const 引用给它。 (const string&s)

4) 算法错误,重写。多想想吧。

5) 析构函数错误,它不会杀死子节点但会进行无效的释放,你需要一个循环。

6) 我会使用 std::vector&lt;Tree*&gt; 而不是 [max] 子树的数组

我把函数想象成...

bool travel_point(const Tree *tree, const string& s, stack<int>& result)

然后使用它...

stack<int> path;
if (travel_point(mytree, "ciao", path))
{
    // print path
}

【讨论】:

  • 我明白了......我的递归肯定有问题,谢谢那些提醒......
  • 好:) 是一个很好的练习,不是那么简单,你可以从中学到很多东西。如果您需要更多帮助,请询问
【解决方案2】:

这会崩溃和燃烧。您正在返回一个指向临时数组“a”的指针。也许您打算将“a”作为参数传递给函数。但是:函数应该返回什么?

顺便说一句:递归个好主意。

【讨论】:

  • 我希望该函数返回 NULL 或所有内容。因此正确的路径将以任何方式返回,而错误的路径返回 NULL。
  • 返回指向函数中分配的本地数组的指针将导致 UNDEFINED BEHAVIOR。
猜你喜欢
  • 1970-01-01
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 2012-02-06
  • 1970-01-01
  • 1970-01-01
  • 2023-02-09
  • 2016-03-09
相关资源
最近更新 更多