繁体   English   中英

在树中检查给定节点是否是另一个节点的祖先

[英]In tree check if given node is ancestor of another

我有一个问题-如果给定2个节点(A,B)是B的祖先,我需要回答这个问题。我知道可能的解决方案是获取进入节点的时间和离开节点的时间。 基于此,我可以快速计算关系。 如何使用DFS获得那些无法通过重复实现的“时间戳”?

我不是算法和C ++方面的专家,这就是为什么我要问。

使用标准的增强线程索引(ATI-请参见下面提供的参考),该索引提供了节点长度数据结构(通常是数组),无法在恒定时间内回答A是否是B的祖先的问题。

如果存储每个节点的predthreaddepth (构成ATI方案中的基本数据结构),则可以在O(N)时间内完成A是否是B的祖先的问题-只需从B回溯即可使用pred数据结构,直到到达root并检查是否遇到A

但是,您可以对每个节点执行上述操作作为预处理步骤,然后拥有一个新的节点长度数组,即每个节点的ancestor ,它指示另一个节点是否是其祖先。

参考: Bazaara,Jarvis和Sherali第482页。

我找到了一种方法。 如果您的树在邻接列表中,那么您可以进行预处理。 对于每个节点,您需要在输入值时以及在DFS中离开值时分配值,然后可以在固定时间内检查它:

if (timeIn[b] >= timeIn[a] && timeIn[b] <= timeOut[a]) {
   printf("YES\n");
}
else {
   printf("NO\n");
}

如果a是b的祖先。

DFS:

// INITIALIZE VARs
int time = 0;
stack<int> stackOfChildNodes;
// put root of tree
stackOfChildNodes.push(first);
// go with DFS
while (!stackOfChildNodes.empty()) {
    int current = stackOfChildNodes.top();
    stackOfChildNodes.pop();
    // if node was not visited (time is not set)
    if (timeIn[current] == -1) {
        timeIn[current] = time; // node visited
        time++; // increase time to go further
        stackOfChildNodes.push(current); // include node in processing to leave it in future
        int child = children[current];
        // add descendants to process them
        while (child != 0) {
            stackOfChildNodes.push(child);
            child = descendants[child];
        }
    }
    // if node was visited, so we gonna leave him now
    if (timeIn[current] != -1) {
        timeOut[current] = time-1;
    }
}

暂无
暂无

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

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