树数据结构问题:如何填充所有树节点的所有中序后继指针?

发布于 2024-10-05 12:10:33 字数 1442 浏览 0 评论 0原文

树节点包含 3 个指针 *left、*right 和 *Successor 。

Struct node{
     int data;
     struct node *left;
     struct node *right;
     struct node *successor; 
}; 


        A
       /  \
      B    C
     / \  / \
    D   E F  G

INORDER 遍历:DBEAFCG *注意:* 中序后继者是 F、C 和 G。

  **Function prototype:** void  FillSuccessorNodes( struct node *root);

树的根节点给我们,我们需要为所有节点填充后继者指针。

情况 1) 某些后继指针可能为 NULL 。在这种情况下,您必须用立即顺序后继者填充该指针。

示例:如果 A->Successor == NULL,则填充 A->Successor = F

情况 2) 某些 Successor 指针可能已经指向正确的后继者。这种情况下你不需要修改后继指针。

示例: 1) A->successor = F 是有效

     2) A->successor = C is valid

     3) A-successor = G is valid  . All these three cases you no need to modify successor pointer since these already pointing to correct successor nodes.  

情况 3) 某些后继指针非 NULL,但这些指针指向无效后继,即它可能是有序后继或某些垃圾值。在这种情况下,您必须用直接后继节点填充这些节点。

示例:

     1) A->successor = B is invalid since B is not successor node , so we have to correct it to A->successor = F.

     2) A->successor = 0x23237463478 is invalid since it is pointing to garbage value. So we we have to correct it to A->successor = F. 

1) 面试官问我时间复杂度为 O(n) 的高效解决方案。允许额外的空间。 2)她给出了一些提示,即我们可以使用哈希。

如果您知道这个问题的解决方案,请告诉我。

Tree node contains 3 pointers *left, *right and *Successor .

Struct node{
     int data;
     struct node *left;
     struct node *right;
     struct node *successor; 
}; 


        A
       /  \
      B    C
     / \  / \
    D   E F  G

INORDER Traversal: DBEAFCG
*Note:* A inorder successors are F,C and G.

  **Function prototype:** void  FillSuccessorNodes( struct node *root);

Tree's root node given to us and we need to fill successor pointer for all nodes.

case 1) some of the Successor pointers may be NULL . This case you have to fill that pointer with immediate Inorder Successor.

Example: if A->Successor == NULL, then fill A->Successor = F

case 2) some of the Successor pointers may already points to correct successors. This case You no need to modify successor pointers.

Example: 1) A->successor = F is valid

     2) A->successor = C is valid

     3) A-successor = G is valid  . All these three cases you no need to modify successor pointer since these already pointing to correct successor nodes.  

case 3) Some of the successor pointers are not NULL but these pointers pointing to INVALID successors i.e it could be inorder successor or some garbage value. This case you have to fill these nodes with immediate successor nodes.

Example:

     1) A->successor = B is invalid since B is not successor node , so we have to correct it to A->successor = F.

     2) A->successor = 0x23237463478 is invalid since it is pointing to garbage value. So we we have to correct it to A->successor = F. 

1) Interviewer asked me time efficient solution in O(n) time complexity. Extra space allowed.
2) she gave some hint i.e we can use HASHing.

If you know the solution for this problem, please let me know .

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不美如何 2024-10-12 12:10:34

这个问题和提示似乎误导了我。由于无论如何您都必须检查所有节点以检查它们的后继节点是否无效,并且由于您必须计算后继节点以了解无效的含义,因此您不妨使用标准的 O(n) 中序遍历,例如:

#include <utility>
using namespace std;

typedef pair<node*, node*> node_pair;

node_pair setInOrderSuccessors(node* root)
{
    node_pair result(root, root);

    if (root->left) {
        const node_pair pair = setInOrderSuccessors(root->left);
        result.first = pair.first;
        pair.second->successor = root;
    }

    if (root->right) {
        const node_pair pair = setInOrderSuccessors(root->right);
        result.second = pair.second;
        root->successor = pair.first;
    }

    return result;
}

void  FillSuccessorNodes(node *root)
{
    const node_pair pair = setInOrderSuccessors(root);
    pair.second->successor = 0;
}

The question and hint seem misleading to me. Since you have to check all nodes anyway to check if their successors are invalid, and since you have to compute the successor to know what invalid means, you might as well use a standard O(n) inorder traversal, e.g.:

#include <utility>
using namespace std;

typedef pair<node*, node*> node_pair;

node_pair setInOrderSuccessors(node* root)
{
    node_pair result(root, root);

    if (root->left) {
        const node_pair pair = setInOrderSuccessors(root->left);
        result.first = pair.first;
        pair.second->successor = root;
    }

    if (root->right) {
        const node_pair pair = setInOrderSuccessors(root->right);
        result.second = pair.second;
        root->successor = pair.first;
    }

    return result;
}

void  FillSuccessorNodes(node *root)
{
    const node_pair pair = setInOrderSuccessors(root);
    pair.second->successor = 0;
}
把回忆走一遍 2024-10-12 12:10:34

只需要对中序遍历稍作修改,记住前驱并设置前驱->后继=当前即可。

stack<node*> s;
node* t = root ,*pred=NULL;
while(true)
{
    if(t){
            s.push(t);
            t= t->left; 
            continue;
    }           
    if(s.empty()) { break;}
    t= s.top();
    if(NULL != pred && pred->succesor != t)
    {
        pred->succesor = t;     
    }
    pred  = t; 
    s.pop();        
    cout<<t->c;
    t= t->right; 
}

It require only a small modification to inorder traversal , you have to remeber the predecessor and set predecessot->successor = current.

stack<node*> s;
node* t = root ,*pred=NULL;
while(true)
{
    if(t){
            s.push(t);
            t= t->left; 
            continue;
    }           
    if(s.empty()) { break;}
    t= s.top();
    if(NULL != pred && pred->succesor != t)
    {
        pred->succesor = t;     
    }
    pred  = t; 
    s.pop();        
    cout<<t->c;
    t= t->right; 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文