Algorithm 关于树数据结构的问题:如何填充所有树节点的所有顺序后续指针?
树节点包含3个指针*左、*右和*后继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
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有效时的情况不匹配