可以有两种节点: -
对于(1)部分以下功能似乎工作正常
void printkdistanceNodeDown(node *root, int k)
{
// Base Case
if (root == NULL || k < 0) return;
if (k==0)
{
printf("%d", root->data);
return;
}
// Recur for left and right subtrees
printkdistanceNodeDown(root->left, k-1);
printkdistanceNodeDown(root->right, k-1);
}
我被困在(2)部分,即找到距离的祖先节点&#39; k&#39;来自目标节点。 如何查找第二类节点?
答案 0 :(得分:1)
作为第一步,请通过第三次递归调用(例如
)访问父级printkdistanceNodeDown(root->parent, k-1);
现在,这并不是很有效,因为在像
这样的树中 2
/
1,
距离2的距离3的打印节点将打印1,因为我们可以遵循路径2-> 1-> 2-> 1。树的优良特性是,如果路径像这样翻倍,那么在至少一个例子中,存在像x-> y-> x的子路径。因此,一种可能的解决方法是添加另一个参数node *previous
,该参数指示路径的来源。对于根调用,previous
应为NULL
或某个值与每个有效节点不相等的值。递归调用被重写为
if (root->parent != previous) printkdistanceNodeDown(root->parent, k-1, root);
同样适用于root->left
和root->right
。
答案 1 :(得分:1)
您可以找到从根到目标的距离没有问题。 您可以以相同的方式找到从根到给定祖先节点的距离。
其余的留给你的学习好处,也检查你的作业是否要求给定距离的笔记,或者他们可能想要在给定距离内的笔记
(我假设你在节点上没有&#34; up&#34;指针。)
答案 2 :(得分:0)
让我们通过一个示例二进制树来讨论案例(2),其中节点不是目标节点的后代
100
/ \
8 6
/ \ / \
7 4 1 9
/\ / / /\
2 3 5 10 15 25
Let's say, target Node = 15 and K=4
Output Expected = 10, 8
Step 1:
维护两个堆栈。在其中一个堆栈中放置节点15的所有祖先,直到我们到达root或者直到祖先的数量超过K.这意味着在最坏的情况下,我们必须将祖先一直存储到root。在第二个堆栈存储L or R (Left or Right)
中,取决于将祖先存储在第一个堆栈中时所遵循的路径。此外,维护一个正在运行的计数器,例如cntr
,表示正在推送的元素数量。这里的示例堆栈如下所示:
1st Stack: 2nd Stack:
| | | |
|100| | R |
|6 | | R |
|9 | | L |
和cntr = 3
Step2:
弹出两个堆栈中的元素,并使用参数printkdistanceNodeDown(node *root, int k)
(值为root=100->Left
的节点)和8
调用函数k=k-cntr-1
。
Step3:
递减cntr
并重复步骤2直到堆栈不为空。
注1:在处理堆栈的最后一个元素时,即。 '9'
和'L'
printkdistanceNodeDown()
不会打印任何内容,这确实是预期的。