繁体   English   中英

使用 C++ 中的子级列表在通用树中的两个给定节点之间添加节点并查找路径成本

[英]Add a node and Find Cost of Path between two given nodes in a Generic Tree with List of Children in C++

我需要在其子项包含在列表中的通用树中创建一个添加节点函数。 有 2 个结构体定义了树中的一个节点(它有一个标签,它和它的父亲之间的权重,以及一个指向它的孩子列表的指针)和一个孩子列表中的孩子(它有一个指向子节点和列表中的下一个元素):

struct tree::treeNode {
    Label label;
    Weight weight;
    childrenList children;
}; //(typedef'ed as Tree)

struct tree::childrenListElem {
    treeNode* child;
    childrenListElem* next;
};

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

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 函数中的最后一个 else 中,我需要找到一种方法使 labelOfNodeToAdd 成为 labelOfNodeInTree 的孩子之一。 我是否将其正确添加到列表中? getNode 函数是否因为aux = aux->children->next->child;无法正常工作aux = aux->children->next->child; 线? 我在想象孩子列表时遇到问题,因此我不确定如何分析每个元素(检查它是否是 getNode 中给定标签标识的节点,或者检查它是否存在于具有成员的树中) .

编辑 2:如果可能,我想展示最后一个函数(以查找 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;
}

每次我尝试计算路径时碰巧都会给我带来问题 - 这是总和的问题吗? 或者它没有正确横向?

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

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 循环遍历节点的子节点(例如深一层),递归member调用负责向下一层。

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

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

在这一点上,你不妨重新实现member

bool tree::member(const Label l, const Tree& t) {
  return !isEmpty(getNode(l, t));
}

编辑: 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;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM