打印距离给定节点k处的所有节点

给定二叉树、二叉树中的目标节点和整数值k,打印距离给定目标节点k的所有节点。没有可用的父指针。

null

BinaryTree

考虑图中所示的树 输入:target=指向包含数据8的节点的指针。 root=指向包含数据20的节点的指针。 k=2。 产出:101422 如果目标为14,k为3,则输出 应该是“420”

需要考虑两种类型的节点。 1) 子树中以目标节点为根的节点。例如,如果目标节点是8,k是2,那么这样的节点是10和14。 2) 其他节点,可能是目标的祖先,或其他子树中的节点。对于目标节点8和k为2,节点22属于该类别。 找到第一类节点很容易实现。只需遍历以目标节点为根的子树,并在递归调用中递减k。当k变为0时,打印当前正在遍历的节点(请参见 更多细节)。这里我们把函数称为 printkdistanceNodeDown() . 如何找到第二种类型的节点?对于不在以目标节点为根的子树中的输出节点,我们必须遍历所有祖先。对于每个祖先,我们找到它与目标节点的距离,让距离为d,现在我们转到祖先的其他子树(如果目标在左子树中找到,那么我们转到右子树,反之亦然),并找到与祖先在k-d距离处的所有节点。

以下是上述方法的实现。

C++

#include <iostream>
using namespace std;
// A binary Tree node
struct node
{
int data;
struct node *left, *right;
};
/* Recursive function to print all the nodes at distance k in the
tree (or subtree) rooted with given root. See  */
void printkdistanceNodeDown(node *root, int k)
{
// Base Case
if (root == NULL || k < 0) return ;
// If we reach a k distant node, print it
if (k==0)
{
cout << root->data << endl;
return ;
}
// Recur for left and right subtrees
printkdistanceNodeDown(root->left, k-1);
printkdistanceNodeDown(root->right, k-1);
}
// Prints all nodes at distance k from a given target node.
// The k distant nodes may be upward or downward.  This function
// Returns distance of root from target node, it returns -1 if target
// node is not present in tree rooted with root.
int printkdistanceNode(node* root, node* target , int k)
{
// Base Case 1: If tree is empty, return -1
if (root == NULL) return -1;
// If target is same as root.  Use the downward function
// to print all nodes at distance k in subtree rooted with
// target or root
if (root == target)
{
printkdistanceNodeDown(root, k);
return 0;
}
// Recur for left subtree
int dl = printkdistanceNode(root->left, target, k);
// Check if target node was found in left subtree
if (dl != -1)
{
// If root is at distance k from target, print root
// Note that dl is Distance of root's left child from target
if (dl + 1 == k)
cout << root->data << endl;
// Else go to right subtree and print all k-dl-2 distant nodes
// Note that the right child is 2 edges away from left child
else
printkdistanceNodeDown(root->right, k-dl-2);
// Add 1 to the distance and return value for parent calls
return 1 + dl;
}
// MIRROR OF ABOVE CODE FOR RIGHT SUBTREE
// Note that we reach here only when node was not found in left subtree
int dr = printkdistanceNode(root->right, target, k);
if (dr != -1)
{
if (dr + 1 == k)
cout << root->data << endl;
else
printkdistanceNodeDown(root->left, k-dr-2);
return 1 + dr;
}
// If target was neither present in left nor in right subtree
return -1;
}
// A utility function to create a new binary tree node
node *newnode( int data)
{
node *temp = new node;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
// Driver program to test above functions
int main()
{
/* Let us construct the tree shown in above diagram */
node * root = newnode(20);
root->left = newnode(8);
root->right = newnode(22);
root->left->left = newnode(4);
root->left->right = newnode(12);
root->left->right->left = newnode(10);
root->left->right->right = newnode(14);
node * target = root->left->right;
printkdistanceNode(root, target, 2);
return 0;
}


JAVA

// Java program to print all nodes at a distance k from given node
// A binary tree node
class Node
{
int data;
Node left, right;
Node( int item)
{
data = item;
left = right = null ;
}
}
class BinaryTree
{
Node root;
/* Recursive function to print all the nodes at distance k in
tree (or subtree) rooted with given root. */
void printkdistanceNodeDown(Node node, int k)
{
// Base Case
if (node == null || k < 0 )
return ;
// If we reach a k distant node, print it
if (k == 0 )
{
System.out.print(node.data);
System.out.println( "" );
return ;
}
// Recur for left and right subtrees
printkdistanceNodeDown(node.left, k - 1 );
printkdistanceNodeDown(node.right, k - 1 );
}
// Prints all nodes at distance k from a given target node.
// The k distant nodes may be upward or downward.This function
// Returns distance of root from target node, it returns -1
// if target node is not present in tree rooted with root.
int printkdistanceNode(Node node, Node target, int k)
{
// Base Case 1: If tree is empty, return -1
if (node == null )
return - 1 ;
// If target is same as root.  Use the downward function
// to print all nodes at distance k in subtree rooted with
// target or root
if (node == target)
{
printkdistanceNodeDown(node, k);
return 0 ;
}
// Recur for left subtree
int dl = printkdistanceNode(node.left, target, k);
// Check if target node was found in left subtree
if (dl != - 1 )
{
// If root is at distance k from target, print root
// Note that dl is Distance of root's left child from
// target
if (dl + 1 == k)
{
System.out.print(node.data);
System.out.println( "" );
}
// Else go to right subtree and print all k-dl-2 distant nodes
// Note that the right child is 2 edges away from left child
else
printkdistanceNodeDown(node.right, k - dl - 2 );
// Add 1 to the distance and return value for parent calls
return 1 + dl;
}
// MIRROR OF ABOVE CODE FOR RIGHT SUBTREE
// Note that we reach here only when node was not found in left
// subtree
int dr = printkdistanceNode(node.right, target, k);
if (dr != - 1 )
{
if (dr + 1 == k)
{
System.out.print(node.data);
System.out.println( "" );
}
else
printkdistanceNodeDown(node.left, k - dr - 2 );
return 1 + dr;
}
// If target was neither present in left nor in right subtree
return - 1 ;
}
// Driver program to test the above functions
public static void main(String args[])
{
BinaryTree tree = new BinaryTree();
/* Let us construct the tree shown in above diagram */
tree.root = new Node( 20 );
tree.root.left = new Node( 8 );
tree.root.right = new Node( 22 );
tree.root.left.left = new Node( 4 );
tree.root.left.right = new Node( 12 );
tree.root.left.right.left = new Node( 10 );
tree.root.left.right.right = new Node( 14 );
Node target = tree.root.left.right;
tree.printkdistanceNode(tree.root, target, 2 );
}
}
// This code has been contributed by Mayank Jaiswal


Python3

# Python program to print nodes at distance k from a given node
# A binary tree node
class Node:
# A constructor to create a new node
def __init__( self , data):
self .data = data
self .left = None
self .right = None
# Recursive function to print all the nodes at distance k
# int the tree(or subtree) rooted with given root. See
def printkDistanceNodeDown(root, k):
# Base Case
if root is None or k< 0 :
return
# If we reach a k distant node, print it
if k = = 0 :
print (root.data)
return
# Recur for left and right subtree
printkDistanceNodeDown(root.left, k - 1 )
printkDistanceNodeDown(root.right, k - 1 )
# Prints all nodes at distance k from a given target node
# The k distant nodes may be upward or downward. This function
# returns distance of root from target node, it returns -1
# if target node is not present in tree rooted with root
def printkDistanceNode(root, target, k):
# Base Case 1 : IF tree is empty return -1
if root is None :
return - 1
# If target is same as root. Use the downward function
# to print all nodes at distance k in subtree rooted with
# target or root
if root = = target:
printkDistanceNodeDown(root, k)
return 0
# Recur for left subtree
dl = printkDistanceNode(root.left, target, k)
# Check if target node was found in left subtree
if dl ! = - 1 :
# If root is at distance k from target, print root
# Note: dl is distance of root's left child
# from target
if dl + 1 = = k :
print (root.data)
# Else go to right subtreee and print all k-dl-2
# distant nodes
# Note: that the right child is 2 edges away from
# left child
else :
printkDistanceNodeDown(root.right, k - dl - 2 )
# Add 1 to the distance and return value for
# for parent calls
return 1 + dl
# MIRROR OF ABOVE CODE FOR RIGHT SUBTREE
# Note that we reach here only when node was not found
# in left subtree
dr = printkDistanceNode(root.right, target, k)
if dr ! = - 1 :
if (dr + 1 = = k):
print (root.data)
else :
printkDistanceNodeDown(root.left, k - dr - 2 )
return 1 + dr
# If target was neither present in left nor in right subtree
return - 1
# Driver program to test above function
root = Node( 20 )
root.left = Node( 8 )
root.right = Node( 22 )
root.left.left = Node( 4 )
root.left.right = Node( 12 )
root.left.right.left = Node( 10 )
root.left.right.right = Node( 14 )
target = root.left.right
printkDistanceNode(root, target, 2 )
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)


C#

using System;
// C# program to print all nodes at a distance k from given node
// A binary tree node
public class Node
{
public int data;
public Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
public class BinaryTree
{
public Node root;
/* Recursive function to print all the nodes at distance k in
tree (or subtree) rooted with given root. */
public virtual void printkdistanceNodeDown(Node node, int k)
{
// Base Case
if (node == null || k < 0)
{
return ;
}
// If we reach a k distant node, print it
if (k == 0)
{
Console.Write(node.data);
Console.WriteLine( "" );
return ;
}
// Recur for left and right subtrees
printkdistanceNodeDown(node.left, k - 1);
printkdistanceNodeDown(node.right, k - 1);
}
// Prints all nodes at distance k from a given target node.
// The k distant nodes may be upward or downward.This function
// Returns distance of root from target node, it returns -1
// if target node is not present in tree rooted with root.
public virtual int printkdistanceNode(Node node, Node target, int k)
{
// Base Case 1: If tree is empty, return -1
if (node == null )
{
return -1;
}
// If target is same as root.  Use the downward function
// to print all nodes at distance k in subtree rooted with
// target or root
if (node == target)
{
printkdistanceNodeDown(node, k);
return 0;
}
// Recur for left subtree
int dl = printkdistanceNode(node.left, target, k);
// Check if target node was found in left subtree
if (dl != -1)
{
// If root is at distance k from target, print root
// Note that dl is Distance of root's left child from
// target
if (dl + 1 == k)
{
Console.Write(node.data);
Console.WriteLine( "" );
}
// Else go to right subtree and print all k-dl-2 distant nodes
// Note that the right child is 2 edges away from left child
else
{
printkdistanceNodeDown(node.right, k - dl - 2);
}
// Add 1 to the distance and return value for parent calls
return 1 + dl;
}
// MIRROR OF ABOVE CODE FOR RIGHT SUBTREE
// Note that we reach here only when node was not found in left
// subtree
int dr = printkdistanceNode(node.right, target, k);
if (dr != -1)
{
if (dr + 1 == k)
{
Console.Write(node.data);
Console.WriteLine( "" );
}
else
{
printkdistanceNodeDown(node.left, k - dr - 2);
}
return 1 + dr;
}
// If target was neither present in left nor in right subtree
return -1;
}
// Driver program to test the above functions
public static void Main( string [] args)
{
BinaryTree tree = new BinaryTree();
/* Let us construct the tree shown in above diagram */
tree.root = new Node(20);
tree.root.left = new Node(8);
tree.root.right = new Node(22);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(12);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(14);
Node target = tree.root.left.right;
tree.printkdistanceNode(tree.root, target, 2);
}
}
// This code is contributed by Shrikant13


Javascript

<script>
// Javascript program to print all nodes at a distance k from given node
// A binary tree node
class Node
{
constructor(item)
{
this .data = item;
this .left = null ;
this .right = null ;
}
}
var root = null ;
/* Recursive function to print all the nodes at distance k in
tree (or subtree) rooted with given root. */
function printkdistanceNodeDown(node, k)
{
// Base Case
if (node == null || k < 0)
{
return ;
}
// If we reach a k distant node, print it
if (k == 0)
{
document.write(node.data);
document.write( "<br>" );
return ;
}
// Recur for left and right subtrees
printkdistanceNodeDown(node.left, k - 1);
printkdistanceNodeDown(node.right, k - 1);
}
// Prints all nodes at distance k from a given target node.
// The k distant nodes may be upward or downward.This function
// Returns distance of root from target node, it returns -1
// if target node is not present in tree rooted with root.
function printkdistanceNode(node, target, k)
{
// Base Case 1: If tree is empty, return -1
if (node == null )
{
return -1;
}
// If target is same as root.  Use the downward function
// to print all nodes at distance k in subtree rooted with
// target or root
if (node == target)
{
printkdistanceNodeDown(node, k);
return 0;
}
// Recur for left subtree
var dl = printkdistanceNode(node.left, target, k);
// Check if target node was found in left subtree
if (dl != -1)
{
// If root is at distance k from target, print root
// Note that dl is Distance of root's left child from
// target
if (dl + 1 == k)
{
document.write(node.data);
document.write( "<br>" );
}
// Else go to right subtree and print all k-dl-2 distant nodes
// Note that the right child is 2 edges away from left child
else
{
printkdistanceNodeDown(node.right, k - dl - 2);
}
// Add 1 to the distance and return value for parent calls
return 1 + dl;
}
// MIRROR OF ABOVE CODE FOR RIGHT SUBTREE
// Note that we reach here only when node was not found in left
// subtree
var dr = printkdistanceNode(node.right, target, k);
if (dr != -1)
{
if (dr + 1 == k)
{
document.write(node.data);
document.write( "<br>" );
}
else
{
printkdistanceNodeDown(node.left, k - dr - 2);
}
return 1 + dr;
}
// If target was neither present in left nor in right subtree
return -1;
}
// Driver program to test the above functions
/* Let us construct the tree shown in above diagram */
root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
var target = root.left.right;
printkdistanceNode(root, target, 2);
// This code is contributed by importantly.
</script>


输出:

420

时间复杂性: 首先,时间复杂度看起来比O(n)大,但如果我们仔细观察,我们可以发现没有节点被遍历超过两次。因此,时间复杂度为O(n)。 本文由 普拉桑特·库马尔 。如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请发表评论

替代解决方案:

  1. 从根节点获取路径并添加到列表中
  2. 对于路径中的每个第i个元素,只需迭代并打印(K-i)个距离节点。

JAVA

import java.io.*;
import java.util.*;
class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode() {}
public TreeNode( int val) { this .val = val; }
}
class GFG {
List<TreeNode> path = null ;
//Finding all the nodes at a distance K from target
//node.
public List<Integer> distanceK(TreeNode root,
TreeNode target, int K)
{
path = new ArrayList<>();
findPath(root, target);
List<Integer> result = new ArrayList<>();
for ( int i = 0 ; i < path.size(); i++) {
findKDistanceFromNode(
path.get(i), K - i, result,
i == 0 ? null : path.get(i - 1 ));
}
//Returning list of all nodes at a distance K
return result;
}
// Blocker is used for ancestors node if target at
//left then we have to go in right or if target at
// right then we have to go in left.
public void findKDistanceFromNode(TreeNode node,
int dist,
List<Integer> result,
TreeNode blocker)
{
if (dist < 0 || node == null
|| (blocker != null && node == blocker)) {
return ;
}
if (dist == 0 ) {
result.add(node.val);
}
findKDistanceFromNode(node.left, dist - 1 , result,
blocker);
findKDistanceFromNode(node.right, dist - 1 , result,
blocker);
}
//Finding the path of target node from root node
public boolean findPath(TreeNode node, TreeNode target)
{
if (node == null )
return false ;
if (node == target || findPath(node.left, target)
|| findPath(node.right, target)) {
path.add(node);
return true ;
}
return false ;
}
// Driver program to test the above functions
public static void main(String[] args)
{
GFG gfg = new GFG();
/* Let us construct the tree shown in above diagram */
TreeNode root = new TreeNode( 20 );
root.left = new TreeNode( 8 );
root.right = new TreeNode( 22 );
root.left.left = new TreeNode( 4 );
root.left.right = new TreeNode( 12 );
root.left.right.left = new TreeNode( 10 );
root.left.right.right = new TreeNode( 14 );
TreeNode target = root.left.right;
System.out.println(gfg.distanceK(root, target, 2 ));
}
}


输出

[4, 20]

时间复杂性: O(n)

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享