Algorithm 关于树数据结构的问题:如何填充所有树节点的所有顺序后续指针?

Algorithm 关于树数据结构的问题:如何填充所有树节点的所有顺序后续指针?,algorithm,data-structures,recursion,tree,Algorithm,Data Structures,Recursion,Tree,树节点包含3个指针*左、*右和*后继 Struct node{ int data; struct node *left; struct node *right; struct node *successor; }; A / \ B C / \ / \ D E F G 顺序遍历:DBEAFCG *注:*A顺序的后继者是F、C和G **Function prototype

树节点包含3个指针*左、*右和*后继

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


        A
       /  \
      B    C
     / \  / \
    D   E F  G
顺序遍历:DBEAFCG *注:*A顺序的后继者是F、C和G

  **Function prototype:** void  FillSuccessorNodes( struct node *root);
树的根节点给了我们,我们需要为所有节点填充后续指针

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

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

案例2)某些后续指针可能已经指向正确的后续指针。在这种情况下,您不需要修改后续指针

示例:1)A->继任者=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)一些后继指针不是空的,但这些指针指向无效的后继指针,即它可能是顺序后继指针或某个垃圾值。在这种情况下,必须用直接的后续节点填充这些节点

例如:

     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) 她给出了一些提示,即我们可以使用散列。


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

这个问题和提示似乎对我有误导性。由于您必须检查所有节点以检查其后继节点是否无效,并且由于您必须计算后继节点以了解无效的含义,因此您最好使用标准的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;
}
#包括
使用名称空间std;
typedef对节点\ u对;
节点\对setInOrderSuccessors(节点*根)
{
节点对结果(根,根);
如果(根->左){
const node_pair pair=setInOrderSuccessors(根->左);
result.first=pair.first;
第二对->后续=根;
}
如果(根->右){
const node_pair pair=setInOrderSuccessors(根->右);
result.second=pair.second;
root->successive=pair.first;
}
返回结果;
}
无效填充成功节点(节点*根)
{
const node_pair pair=setInOrderSuccessors(根);
第二对->后继者=0;
}

它只需要对顺序遍历进行一个小的修改,您必须记住前一个,并将predecessort->succession=current设置为predecessort->succession=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; 
}
stacks;
node*t=root,*pred=NULL;
while(true)
{
if(t){
s、 推(t);
t=t->左;
继续;
}           
如果(s.empty()){break;}
t=s.top();
if(NULL!=pred&&pred->succesor!=t)
{
pred->succesor=t;
}
pred=t;
s、 pop();
库特里赫特;
}

这是对正常顺序遍历的一个相当直接的修改。编写代码,并考虑如何找到当前节点的后续节点。@siva:您有O(n)解决方案吗?这似乎与A-succession=G有效时的情况不匹配