Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.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++ 如何在C++;对于通用树数据结构?_C++_Data Structures_Tree - Fatal编程技术网

C++ 如何在C++;对于通用树数据结构?

C++ 如何在C++;对于通用树数据结构?,c++,data-structures,tree,C++,Data Structures,Tree,我有一个结构s: struct s{ int x; /******************************************************************** * NoOfchild doesn't represent maximum no of children for node s . * This represent no of children node s have at any given instance . **

我有一个结构s:

struct s{
   int x;
  /********************************************************************
   *  NoOfchild doesn't represent maximum no of children for node s . 
   *  This represent no of children node s have at any given instance . 
   *********************************************************************/      
   int NoOfChild; 
   s  **child;
}
我想使用**动态声明指针数组。节点s被逐个添加到数组中。有任何方法可以实现这一点。这棵树将被用来做蔬菜

**表示节点s。我不希望
同时声明一个节点的所有子节点
,也就是说,我希望在需要
时逐个添加子节点
。e、 g.o添加为根,然后节点1添加为根的子节点(如果需要),然后添加节点2,依此类推。[****]表示节点x的子节点

编辑:
对于一个给定的节点,人们假设NoOfChild为
子节点的最大数量,这是不正确的,这里NoOfChild表示一个节点在给定实例中有多少子节点,它可能会根据需求或时间而变化。
说明:
最初,节点0已初始化,因此它有零(0)个子节点。
然后添加节点1作为节点0的子节点,以便o->NoOfChild=1和1->NoOfChild=0
然后添加节点[*]作为节点1的子节点so 0->NoOfChild=1和1->NoOfChild=1
然后添加2作为节点0的子节点,因此0->NoOfChild=2和1->NoOfChild=1
等等

编辑:

最后使用的
向量子对象

对于常规树数据结构,您可以使用:-

 struct tree{
 int element;
 struct tree *firstchild;
 struct tree *nextsibling;
 };
元素包含要插入节点的数据

FirstChild包含节点的第一个子节点

nextsibling包含同一父节点的另一个子节点。 例如:-

   A

 B  C  D

EF  G     H
然后
A->firstchild=B;
B->nextsibling=C;
C->nextsibling=D;
B->firstchild=E;
E->nextsibling=F;
C->firstchild=g;
D->firstchild=H


未指定的其他值可以视为空值

第一个答案是:你没有。像注释中的每个人一样使用容器类

第二个答案是:动态分配:

void addNewChild(s *into, s* new_child)
{
   s **tmp_s = new s*[into->NoOfChild+1];    ///< will throw if allocation fails

   for(int i=0; i<into->NoOfChild; i++) tmps[i] = into->child[i];  ///< use a memcpy instead
   tmps[into->NoOfChild++] = new_child;

   s **del_s = into->child;
   into->child = tmp_s;
   delete[] del_s;
}
void addNewChild(s*into,s*new_child)
{
s**tmp_s=new s*[into->NoOfChild+1];//<如果分配失败,将抛出
对于(inti=0;inofchild;i++)tmps[i]=into->child[i];//<使用memcpy代替
tmps[into->NoOfChild++]=新的子项;
s**del_s=into->child;
into->child=tmp\s;
删除[]删除;
}
最后:不要这样做。使用
std::vector
std::vector
,具体取决于一个孩子可以有多少父母。

纯c版本:

struct node
{
    int key;
    int noOfChild;
    struct node** childrenArray;
};

struct node* newNode(int key, int noOfChild)
{
    int i;
    struct node* node = (struct node*) malloc(sizeof(struct node));
    node->key = key;
    node->noOfChild = noOfChild;
    node->childrenArray = (struct node**) malloc(noOfChild * sizeof(struct node*));
    for(i=0;i<noOfChild;i++)
    {
        node->childrenArray[i] = NULL;
    }
    return(node);
}
struct节点
{
int键;
int noOfChild;
结构节点**子数组;
};
结构节点*newNode(int-key,int-noOfChild)
{
int i;
结构节点*节点=(结构节点*)malloc(sizeof(结构节点));
节点->键=键;
节点->noOfChild=noOfChild;
node->childrenArray=(结构节点**)malloc(noOfChild*sizeof(结构节点*);
对于(i=0;ichildrenArray[i]=NULL;
}
返回(节点);
}
自从您标记了c++之后:

#include <vector>
#include <memory>
#include <algorithm>
#include <iostream>

template <class ValueType>
class VariadicTree
{
public:
    VariadicTree(const ValueType& value) : m_value(value), m_size(0)
    {
    }

    VariadicTree<ValueType>& addNode(const ValueType& value)
    {
        m_children.emplace_back(new VariadicTree<ValueType>(value));
        ++m_size;
        return *m_children.back();
    }

    bool leaf()
    {
        return std::all_of(m_children.begin(), m_children.end(),
                           [&](const std::unique_ptr<VariadicTree<ValueType>>& ptr)
                              {return ptr == nullptr;});
    }

    size_t size()
    {
        return m_size;
    }

    const ValueType& value()
    {
        return m_value;
    }

private:
    size_t m_size;
    const ValueType& m_value;
    std::vector<std::unique_ptr<VariadicTree<ValueType>>> m_children;
};

int main()
{
    VariadicTree<int> root(5);
    auto& c1 = root.addNode(4);
    auto& c2 = root.addNode(6);
    auto& c3 = root.addNode(2);

    auto& c11 = c1.addNode(2);

    std::cout << root.leaf() << "\n";
    std::cout << c11.leaf() << "\n";
    std::cout << root.size() << "\n";
    std::cout << c1.size() << "\n";
    std::cout << c11.size() << "\n";

    return 0;
}
#包括
#包括
#包括
#包括
模板
类变量树
{
公众:
变量树(常量值类型和值):m_值(值),m_大小(0)
{
}
变量树和添加节点(常量值类型和值)
{
m_children.emplace_back(新变量树(值));
++m_尺寸;
return*m_children.back();
}
布尔叶
{
return std::all_of(m_children.begin(),m_children.end(),
[&](const std::unique_ptr&ptr)
{return ptr==nullptr;});
}
大小
{
返回m_大小;
}
常量值类型和值()
{
返回m_值;
}
私人:
大小;
常量值类型和m_值;
性病::媒介m_儿童;
};
int main()
{
变异根(5);
auto&c1=root.addNode(4);
auto&c2=root.addNode(6);
auto&c3=root.addNode(2);
auto&c11=c1.addNode(2);
std::coutI使用

struct s{
   int x;
   vector<s*> child ;
}
结构{
int x;
媒介儿童;
}

这有助于更多,因为所有指针/引用都是由STL .< /P>使用“代码>向量< /代码>,或者甚至矢量< /代码>。如果你在C++中使用它,那么使用向量或列表,而不是数组。保存一些内存和头痛。是的,这是可能的,但它不必要复杂。它是树,而不是一般的图形,所以你可以使用数组。

s
而不是
s*
的数组,并避免无用的间接寻址。此外,像
std::vector
这样的容器会让您省去很多麻烦。@user3919801然后您可以做与
std::vector
类似的事情,分配比您需要的更多的内容,区分“大小”(您存储的实际元素数)从“容量”(分配中可以容纳的元素数量)当然,你应该只在C中采用这种方法。如果你使用C++,那么你应该像其他人指出的那样使用<代码> STD::向量< /代码>。一个简单的想法是指向第一个孩子,这个孩子指向下一个兄弟或自己,如果没有其他孩子。我不知道。你在写作中间意外地点击了保存吗?g这个答案?@Ajay不想使用firstchild,nextsibling节点结构。原始空答案的想法是什么?只是把一些东西放在第一位?看起来OP不是在寻找二叉树数据结构,所以您可能需要重新考虑您的answer@user3919801阅读问题下方的评论。自然选择是a
std::vector
用于孩子。它管理重新分配并跟踪数字。很难找到不使用它的理由。最后使用std::vector或std::vector:p在挖掘中,我们不知道一个人可以预先拥有多少孩子,这完全取决于输入数据。我建议使用
std::vector
,因为vector复制的对象是
push_back()
-ed。如果
s
是树状结构的类,复制对象本身将是一个纯粹的地狱(因为
s
struct s{
   int x;
   vector<s*> child ;
}