Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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++_List_Pointers_Path_Tree - Fatal编程技术网

C++ 添加一个节点并在C+;中包含子节点列表的泛型树中查找两个给定节点之间的路径开销+;

C++ 添加一个节点并在C+;中包含子节点列表的泛型树中查找两个给定节点之间的路径开销+;,c++,list,pointers,path,tree,C++,List,Pointers,Path,Tree,我需要在一个泛型树中创建一个addnode函数,它的子节点包含在一个列表中。 有两个结构定义树中的节点(具有标签、节点与其父节点之间的权重以及指向其子节点列表的指针)和子节点列表中的子节点(具有指向子节点的指针和指向列表中下一个元素的指针): 我已经生成的代码在树为空(添加根)时工作。 当我尝试将节点添加到非空树时,我遇到了运行时错误 Output tree::addElem(const Label labelOfNodeInTree, const Label labelOfNodeToAdd,

我需要在一个泛型树中创建一个addnode函数,它的子节点包含在一个列表中。 有两个结构定义树中的节点(具有标签、节点与其父节点之间的权重以及指向其子节点列表的指针)和子节点列表中的子节点(具有指向子节点的指针和指向列表中下一个元素的指针):

我已经生成的代码在树为空(添加根)时工作。 当我尝试将节点添加到非空树时,我遇到了运行时错误

Output tree::addElem(const Label labelOfNodeInTree, const Label labelOfNodeToAdd, const Weight w, Tree& t) {
      if ((labelOfNodeInTree == emptyLabel) && isEmpty(t)) {
        t = createNode(labelOfNodeToAdd, emptyWeight);
        return OK;
      }
    if (((labelOfNodeInTree == emptyLabel) && !isEmpty(t)) ||
       ((labelOfNodeInTree != emptyLabel) && isEmpty(t)))
        return FAILED;
    if (member(labelOfNodeToAdd, t))
        return ALREADY_PRESENT; 
    Tree v = getNode(labelOfNodeInTree, t); //here is where the problems begin to rise
    if (v==emptyTree)
        return FAILED;
    else {
        g = createNode(labelOfNodeToAdd, w);
        v->children->next->child = g;
        g = t;          
        return OK;
    }
}

以下是我实现的createEmpty、getNode、member和isEmpty函数:

bool tree::isEmpty(const Tree& t)
{
   return (t==emptyTree);
}

Tree getNode(const Label & l, const Tree t)
{
    Tree aux = t;
    while (!isEmpty(aux)) {
        if (aux->label == l)
            return aux;
        aux = aux->children->next->child;
    }
    return emptyTree;
}

Tree createNode(const Label l, Weight w)
{
    Tree t = new treeNode;
    t->label = l;
    t->weight = w;
    t->children = emptyChildrenList;
    return t;
}
编辑:我已经按照函数中的建议修改了成员函数:它只在一个节点(输入给定的节点)上工作,而不在整个树上工作:只要我必须在输入给定的树(t节点)的子列表中搜索给定节点,它就可以正常工作。当我试图分析其子节点的子节点时,我不起作用(横穿其他节点上的树)。以下是目前的成员函数:


bool tree::member(const Label l, const Tree& t) {
    if (isEmpty(t))     return false;
    if (t->label == l)  return true;
    for (childrenList aux = t->children; aux; aux = aux->next) {
        Tree g = aux->child; 
        if (g->label == l)
                        return true;
        g->children = g->children->next;
    }
    return false;   
}

如何使函数在给定节点的子节点的子节点列表中搜索给定标签

我认为问题可能出在getNode辅助函数、成员或addElem函数的最后一个函数中,我需要找到一种方法使LabelofNodeAdd成为labelOfNodeInTree的子函数之一。我把它正确地添加到列表中了吗?getNode函数是否因为
aux=aux->children->next->children而工作不好行?我无法想象子元素列表,因此我不确定如何分析每个元素(检查它是否是getNode中给定标签标识的节点,或者检查它是否存在于成员所在的树中)

编辑2:如果可能的话,我想介绍最后一个函数(查找两个给定节点之间路径的成本(权重之和)),因为它使用了已经在这里实现的函数

Weight tree::pathCost(const Label from, const Label to, const Tree& t)
{
    int len = 0;
    Tree da = getNode(from, t);
    Tree a = getNode(to, t);
    if (da == emptyTree || a == emptyTree)
    return notExistingPath;
    if (da == a)
        return 0;
    for (childrenList aux = t->children; aux; aux = aux->next) {
        Tree n = aux->child;
        if (aux->child == a) {
            return 0;
        }
        len += n->weight;
    }
    return len;
}

每次我试图计算一条路径时,它都会给我带来问题——这是和的问题吗?或者它没有正确地横向传输?

正确的
成员实现可能如下所示:

bool tree::member(const Label l, const Tree& t) {
    if (isEmpty(t))     return false;
    if (t->label == l)  return true;
    for (childrenList aux = t->children; aux; aux = aux->next) {
        if (member(l, aux->child))
            return true;
    }
    return false;   
}
for循环遍历节点的子级(例如一级深度),递归
成员
调用负责下一级

getNode
遵循相同的模式,但返回一个

Tree getNode(const Label & l, const Tree t)
{
    if (isEmpty(t))     return emptyTree;
    if (t->label == l)  return const_cast<Tree>(t);
    for (childrenList aux = t->children; aux; aux = aux->next) {
        Tree candidate = getNode(l, aux->child);
        if (!isEmpty(candidate))
            return candidate;
    }
    return emptyTree;
}
编辑:
addElem
的最后一个分支也错误:

Output tree::addElem(const Label labelOfNodeInTree, const Label labelOfNodeToAdd, const Weight w, Tree& t) {
      if ((labelOfNodeInTree == emptyLabel) && isEmpty(t)) {
        t = createNode(labelOfNodeToAdd, emptyWeight);
        return OK;
      }
    if (((labelOfNodeInTree == emptyLabel) && !isEmpty(t)) ||
       ((labelOfNodeInTree != emptyLabel) && isEmpty(t)))
        return FAILED;
    if (member(labelOfNodeToAdd, t))
        return ALREADY_PRESENT; 
    Tree v = getNode(labelOfNodeInTree, t);
    if (v==emptyTree)
        return FAILED;
    else {
        // Get a reference to the first null pointer in the linked list
        childrenListElem*& aux = v->children;
        while (aux) {
            aux = aux->next;
        }

        // Append a new element by overwriting the pointer
        aux = new childrenListElem;
        aux->child = createNode(labelOfNodeToAdd, w);
        aux->next = nullptr;
        return OK;
    }
}

childrenListElem
childrenList
的关系如何?我认为您的遍历过程真的很糟糕
childrenList
childrenListElem
的一个链接列表,因此
Tree::member
需要按照
的思路为(childrenList aux=t->children;aux;aux=aux->next){Tree t=aux->child;…}
做一些事情,同样为
getNode
我这样做了,成员函数工作得更好,但是它仍然没有遍历它的childrenSetting的子节点
g->children=g->children->next
有效地从树中删除一个节点。在
member
的for循环中,您应该在
aux->child
上递归调用
member
,如果返回true,则返回true在循环的
g->children=g->children->next
之后,但它不起作用。我是否应该声明另一个bool变量来存储
成员的结果
?不幸的是,在最后一种情况下,它仍然不起作用,尽管它对我来说似乎也完全正确。这是我的输入文件。当我尝试搜索“catania”时,问题来了:它应该返回true,但它没有返回。当然,您可以在前面插入新的子对象。这要简单得多:
childrenListElem*aux=newchildrenlistelem;aux->next=v->children;aux->child=createNode(labelOfNodeToAdd,w);v->children=aux
添加功能非常有效,谢谢,但是当我需要查找的节点处于最后一级时,该成员仍然会给我一个错误。我不知道这怎么可能。使用调试器逐步完成程序。
bool tree::member(const Label l, const Tree& t) {
  return !isEmpty(getNode(l, t));
}
Output tree::addElem(const Label labelOfNodeInTree, const Label labelOfNodeToAdd, const Weight w, Tree& t) {
      if ((labelOfNodeInTree == emptyLabel) && isEmpty(t)) {
        t = createNode(labelOfNodeToAdd, emptyWeight);
        return OK;
      }
    if (((labelOfNodeInTree == emptyLabel) && !isEmpty(t)) ||
       ((labelOfNodeInTree != emptyLabel) && isEmpty(t)))
        return FAILED;
    if (member(labelOfNodeToAdd, t))
        return ALREADY_PRESENT; 
    Tree v = getNode(labelOfNodeInTree, t);
    if (v==emptyTree)
        return FAILED;
    else {
        // Get a reference to the first null pointer in the linked list
        childrenListElem*& aux = v->children;
        while (aux) {
            aux = aux->next;
        }

        // Append a new element by overwriting the pointer
        aux = new childrenListElem;
        aux->child = createNode(labelOfNodeToAdd, w);
        aux->next = nullptr;
        return OK;
    }
}