Algorithm 给定一个指向二叉树中某个节点的指针和一个根指针,将打印距离给定节点k处的所有节点
可以有两种类型的节点:-Algorithm 给定一个指向二叉树中某个节点的指针和一个根指针,将打印距离给定节点k处的所有节点,algorithm,data-structures,Algorithm,Data Structures,可以有两种类型的节点:- 子树中以给定节点为根的节点 给定节点的祖先节点 对于(1)部分,下面的函数似乎工作正常 void printkdistanceNodeDown(node *root, int k) { // Base Case if (root == NULL || k < 0) return; if (k==0) { printf("%d", root->data); return; } /
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);
}
void printkdistanceNodeDown(节点*root,int k)
{
//基本情况
if(root==NULL | | k<0)返回;
如果(k==0)
{
printf(“%d”,根->数据);
返回;
}
//左子树和右子树的递归
printkdistanceNodeDown(根->左,k-1);
printkdistanceNodeDown(根->右,k-1);
}
我被(2)部分卡住了,即寻找距离目标节点“k”的祖先节点。
如何找到第二种类型的节点?作为第一步,使用第三个递归调用访问父节点,如
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
可以毫无问题地找到从根到目标的距离。
可以用相同的方法找到从根节点到给定祖先节点的距离
剩下的部分留给你学习,还要检查你的作业是否要求在给定的距离上做笔记,或者他们可能需要在给定的距离内做笔记
(我假设节点上没有“向上”指针。)让我们运行一个示例二叉树,并讨论案例(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
算法:
步骤1:
维护两个堆栈。在其中一个堆栈中,放置节点15的所有祖先,直到我们到达根或者祖先的数量超过K。这意味着在最坏的情况下,我们必须将祖先一直存储到根。在第二个堆栈中,根据在第一个堆栈中存储祖先时遵循的路径,存储L或R(左或右)
。另外,维护一个运行计数器,例如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()
不会打印任何内容,这确实是您的意图。请注意,您可以对问题的答案发表评论。如果你愿意的话。