【问题标题】:Question on Tree Data Structure: How can we fill all inorder successor pointer of all tree nodes?关于树数据结构的问题:我们如何填充所有树节点的所有中序后继指针?
【发布时间】:2010-12-01 03:10:17
【问题描述】:

树节点包含 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);

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

case 1) 一些 Successor 指针可能是 NULL 。在这种情况下,您必须使用立即的 Inorder Successor 填充该指针。

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

case 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.  

case 3) 一些后继指针 not 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) 她给出了一些提示,即我们可以使用 HASHing。

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

【问题讨论】:

  • 这是对正常中序遍历的相当直接的修改。编写代码,并考虑如何找到当前节点的继任者。
  • @siva : 你有 O(n) 解决方案吗?

标签: algorithm data-structures recursion tree


【解决方案1】:

问题和提示对我来说似乎具有误导性。由于您必须检查所有节点以检查其后继节点是否无效,并且由于您必须计算后继节点才能知道无效的含义,因此您不妨使用标准的 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;
}

【讨论】:

    【解决方案2】:

    中序遍历只需稍作修改,你必须记住前任并设置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; 
    }
    

    【讨论】:

    • 这似乎与 A-successor = G 有效时的情况不匹配
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 2019-05-24
    相关资源
    最近更新 更多