Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将n元树表示为向量并遍历_C++_Algorithm_Vector_Tree_Trie - Fatal编程技术网

C++ 将n元树表示为向量并遍历

C++ 将n元树表示为向量并遍历,c++,algorithm,vector,tree,trie,C++,Algorithm,Vector,Tree,Trie,我已经实现了一个n元树(更具体地说,是trie),我想知道是否有一种方法可以将它表示为向量并遍历它。对于二叉树,这将是微不足道的(请参阅),但我似乎找不到一种方法来对n元树执行此操作。 我的最终目标是将矢量表示的树存储到一个文件中,对其进行mmap并执行快速查找,而无需将其有效加载到内存中。 将trie与mmap-ped指针一起使用,而不是分配其内部结构,将trie存储在磁盘ad上的一种有效方法也将非常有用 谢谢。任何图形结构都可以表示为节点的平面数组(事实上,计算机内存就是这样工作的)。您只需

我已经实现了一个n元树(更具体地说,是trie),我想知道是否有一种方法可以将它表示为向量并遍历它。对于二叉树,这将是微不足道的(请参阅),但我似乎找不到一种方法来对n元树执行此操作。 我的最终目标是将矢量表示的树存储到一个文件中,对其进行mmap并执行快速查找,而无需将其有效加载到内存中。
将trie与mmap-ped指针一起使用,而不是分配其内部结构,将trie存储在磁盘ad上的一种有效方法也将非常有用


谢谢。

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

这是一个三向树,作为平面
向量

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;
}
变成

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

等。即,每个节点的查找都通过
对象。

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

假设您知道树的节点号

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

代码->

 #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;
}
#包括
#包括
使用名称空间std;
向量调整[100000000];
无效dfs(int);
int main()
{
int i,n,root,PAR;
cin>>n;
//输入行包含n个空格分隔的整数。
//第i个整数表示第i个节点的直接祖先
//将0作为父节点的节点是根节点
i=1;
而(i>par;
如果(par==0)
{
根=i;
}
其他的
{
形容词[par]。推回(i);
}
i++;
}
//树的遍历(按顺序遍历)
dfs(根);
}
无效dfs(int at)
{
向量::迭代器;
it=adj[at].begin();

在你的例子中,你有一个固定数量的子节点(3),如果每个节点都有一个可变数量的子节点(例如一个trie)会怎么样?如果你应该序列化每个节点,如果中间有B和C,并且它们的大小不是固定的(因为它们可以有任意数量的子节点),你怎么能从节点a“跳”到节点D?@SimoneMargaritelli在trie中,您有固定数量的子项、字母表的元素,或者如果您规定所有输入都是字节字符串,则只有256个(对于压缩,您实际上可以将它们视为半字节字符串,存储16个子项,并将节点数增加一倍)
template
-将这些结构化为
template struct Node{…
@larsmans是的,标准实现是使用
Node*子节点[256]
但是我使用一个链表,在需要时增加它,每个节点都是一个
struct{uint8_t值;void*数据;ll_t子节点;}
…使用的内存更少:)@SimoneMargaritelli在正常情况下,是的。也许你应该看看压缩方案。正是我想到的,只需保留偏移量并将其用作指向文件中jmp访问的节点指针,但这似乎是一个缓慢的解决方案,所以我问:)
 #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;
}