遍历c ++中的常规树

时间:2016-07-07 18:23:25

标签: c++ algorithm tree

我试图遍历一般树。出于这个例子的目的,我有这个结构来保存我的子和父关系。

struct DataItem {
    int id;
    DataItem* root;
    vector<DataItem*> children;
};

与二叉树遍历相比,我没有使用* left和* right,因为可能有多个节点。为了遍历代码,我使用这两个方法,称为constructMap,然后是traverseTree。

void traverseTree(std::vector<int>::iterator current, std::vector<int>::iterator end,
    std::vector<int>::iterator next, DataItem *root) {
    while (current != end) {
        DataItem *childNode;
        childNode->id = *current;
        childNode->root = root;
        if (*current + 1 == *next) {
            root->children.push_back(childNode);
        } else {
            // traverse the next tree
            traverseTree(++current, end, ++next, childNode);
        }
        ++next;
        ++current;
    }
}


void constructMap(std::vector<int>::iterator start, std::vector<int>::iterator end) {
    auto next = std::next(start, 1);
    DataItem *parentNode;
    parentNode->id = *start;
    parentNode->root = NULL;
    traverseTree(++start, end, ++next, parentNode);
    cout << " at the end " << endl;
}

我还没有测试逻辑看到遍历实际上是有用的,虽然我认为它没有,但我一直收到以下错误:

Segmentation fault (core dumped)

在一些注释之后,当我调用此调用时,它会发生在constructMap中:

parentNode->id = *start;

如果我做这样的事情:

int val = *start;
parentNode->id = val;

我能够传递此分段错误并继续前进。

我将向量的迭代器传递给我的地图进行处理,包含如下内容:1,3,4,5,7,8,10

constructMap(allNumbers.begin(), allNumbers.end());

2 个答案:

答案 0 :(得分:3)

问题在于您尝试访问未初始化的指针parentNode。也许把它变成一个简单的对象:

DataItem parentNode;
parentNode.id = *start;
parentNode.root = NULL;
traverseTree(++start, end, ++next, &parentNode);

答案 1 :(得分:0)

如果可能,我不会使用原始指针。使用普通对象或智能指针,例如 std::unique_ptr 或 std::shared_ptr。

然后要遍历树,您可以使用递归 lambda 函数。我做了一个例子program

#include <functional>
#include <iostream>
#include <vector>
using namespace std;

struct Node {
  Node(int id) : Id(id) {}
  int Id;
  vector<Node> Children;
};

int main(void) {
  int id{};
  Node n0(id++);
  n0.Children.emplace_back(id++);
  n0.Children.emplace_back(id++);
  n0.Children.emplace_back(id++);
  auto &n1 = n0.Children.back();
  n1.Children.emplace_back(id++);
  n1.Children.emplace_back(id++);
  n1.Children.emplace_back(id++);
  n1.Children.emplace_back(id++);
  auto &n2 = n1.Children.back();

  std::function<void(const Node &)> visit = [&](const Node &n) {
    std::cout << n.Id << "\n";
    for (const Node &c : n.Children) {
      visit(c);
    }
  };

  visit(n0);
}