表示并遍历n-ary树作为向量

时间:2014-04-08 15:44:39

标签: c++ algorithm vector tree trie

我已经实现了一个n-ary树(更具体地说,是一个trie),我想知道是否有一种方法来表示和遍历它作为向量。使用一个简单的二叉树(参见this question)但我似乎找不到使用n-ary树执行此操作的方法。 我的最终目标是将矢量表示树存储到文件中,对其进行mmap并执行快速查找,而无需将其有效地加载到内存中。
使用mmap-ped指针将磁带广告存储在磁盘广告上而不是分配其内部结构的有效方法也很棒。

感谢。

3 个答案:

答案 0 :(得分:2)

如果你有一棵树,其中每个节点n都有k个子节点,那么你可以继续将节点n的子节点放在数组中的位置k * n + m,其中m在0和k-1之间。如果每个节点都有k个或更少的子节点,这也可以工作,但是如果很多节点的子节点少于k个,它将使用比所需更多的内存。我知道将树存储为节点具有不同子节点数的数组的另一种方法是存储辅助阵列,其中每个节点将偏移量存储到原始数组中以找到该节点的子节点然后你也可以存储每个节点的子节点数,或者只是查找下一个节点的子节点的偏移量,以确定该节点有多少个子节点。

答案 1 :(得分:0)

任何图形结构都可以表示为一个平面的节点数组(事实上,这就是计算机内存的工作原理)。您只需要使用索引而不是指针,因为当vector增长或结构为mmap时,指针无效。

这是一个三维树作为平面vector

struct Node {
    Node(int data) : payload(data)
    {
        for (int i = 0; i < 3; i++) {
            child[i] = (size_t)(-1);  // invalid
        }
    }

    int payload;
    size_t child[3];
};

typedef std::vector<Node> Tree;

void add_node(Tree &t, size_t parent, int child_index, int payload)
{
    t.push_back(Node(payload));
    t[parent].child[child_index] = t.size() - 1;
}

您需要单独的逻辑来插入根节点,因为它没有父节点。此外,如果您想要一个可以跨平台使用mmap'd文件的版本,您最好使用固定大小的索引类型,而不是特定于平台的intsize_t

遍历代码与指针结构相同,但

除外
next = node->child[1]

变为

t[t[node_idx].child[1]]

等。即每个节点查询都通过Tree对象。

答案 2 :(得分:0)

假设您知道树的节点号

您可以将adj向量的大小更改为合适的值

代码 - &GT;

 #include<iostream>
 #include<vector>
using namespace std;
vector<int> adj[100000000];
void dfs(int);
int main()
{

    int i,n,root,par;
    cin>>n;
     //Input line contains n space separated integers.
    // The ith integer represents the immediate ancestor of the ith node
   // Node having 0 as parent node is the Root Node
    i=1;
    while(i<=n)
    {
        cin>>par;

        if(par==0)
        {
            root=i;
        }
        else
        {
            adj[par].push_back(i);
        }
        i++;
    }
    //traversal of the Tree(Inorder traversal)
   dfs(root);

    }

    void dfs(int at)
   {
vector<int>::iterator it;
it=adj[at].begin();
cout<<*it<<" ";
while(it!=adj[at].end())
{
    dfs((*it));
    it++;
}
return;
}

希望这可能会有所帮助