Java 在二叉树中查找两个节点之间的路径
我有以下简单的树: 我的目标是找到两个管理器节点之间的路径 这两个节点将在cmd中选择输入 因此,用户可能会键入“java BinaryTree manager1 manager2”,输出将显示到达第二个管理器所需的路径。此示例应输出以下内容: 'Manager1>BossJava 在二叉树中查找两个节点之间的路径,java,data-structures,binary-tree,nodes,args,Java,Data Structures,Binary Tree,Nodes,Args,我有以下简单的树: 我的目标是找到两个管理器节点之间的路径 这两个节点将在cmd中选择输入 因此,用户可能会键入“java BinaryTree manager1 manager2”,输出将显示到达第二个管理器所需的路径。此示例应输出以下内容: 'Manager1>Boss
public class BinaryTree
{
public static void main(String[] args)
{
Node boss = new Node(1);
Node manager1 = new Node(2);
Node manager2 = new Node(3);
boss.left = manager1;
boss.right = manager2;
String path = findPath(args[0], args[1]);
System.out.println(path);
}
static class Node
{
Node left;
Node right;
int value;
public Node(int value)
{
this.value = value;
}
}
}`
感谢您的帮助:)一般来说,您必须找到从根节点到每个节点的路径,并将它们合并在一起 你如何找到路径取决于树的排列;在最坏的情况下,它需要完全遍历树 在合并步骤中,删除两条路径中的所有公共祖先,但跟踪最近的公共祖先。您想要的路径与manager 1的路径相反,然后是最近的共同祖先(“图中的Boss”),然后是manager 2的路径 确保适应一个管理器是另一个管理器的祖先的情况(我描述的合并过程仍然有效,但其中一个修剪路径将为空)。还要确保捕获或适应manager 1==manager 2的情况
如果您的树的结构超出了简单的树拓扑结构,则可以优化上述部分,尤其是路径查找。以下是打印两个节点之间路径的程序
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class PrintPath {
static List<Node> path = new ArrayList<Node>();
static boolean foundBoth;
/**
* @param args
*/
public static void main(String[] args) {
Node root = Node.createTree();
printPath(root,9,11);
System.out.println(path);
}
static boolean printPath(Node root,int val1 ,int val2){
if(root==null){
return false;
}
if(root.data == val1 || root.data == val2){
addToPath(root);
if(!foundBoth)
foundBoth = findDown(root,(root.data==val1)?val2:val1);
return true;
}
if(!foundBoth){
boolean left = printPath(root.getLeft(), val1, val2);
if(left){
addToPath(root);
}
boolean right = printPath(root.getRight(), val1, val2);
if(right)
addToPath(root);
return (left|| right);
}else{
return true;
}
}
private static void addToPath(Node root) {
path.add(root);
}
static boolean findDown(Node root,int val2){
if(root == null){
return false;
}
if(root.data == val2){
addToPath(root);
return true;
}
boolean left = findDown(root.getLeft(), val2);
if(left){
addToPath(root);
return true;
}
boolean right = findDown(root.getRight(), val2);
if(right){
addToPath(root);
return true;
}
return false;
}
}
import java.util.ArrayList;
导入java.util.List;
导入java.util.Stack;
公共类打印路径{
静态列表路径=新的ArrayList();
静态布尔值同时存在;
/**
*@param args
*/
公共静态void main(字符串[]args){
Node root=Node.createTree();
打印路径(根,9,11);
System.out.println(路径);
}
静态布尔打印路径(节点根,int-val1,int-val2){
if(root==null){
返回false;
}
if(root.data==val1 | | root.data==val2){
addToPath(根);
如果(!foundBoth)
foundBoth=findDown(根,(根.数据==val1)?val2:val1);
返回true;
}
如果(!foundBoth){
布尔左=打印路径(root.getLeft(),val1,val2);
如果(左){
addToPath(根);
}
布尔右=打印路径(root.getRight(),val1,val2);
如果(右)
addToPath(根);
返回(左| |右);
}否则{
返回true;
}
}
私有静态void addToPath(节点根){
添加(根目录);
}
静态布尔findDown(节点根,int-val2){
if(root==null){
返回false;
}
if(root.data==val2){
addToPath(根);
返回true;
}
布尔左=findDown(root.getLeft(),val2);
如果(左){
addToPath(根);
返回true;
}
boolean right=findDown(root.getRight(),val2);
如果(右){
addToPath(根);
返回true;
}
返回false;
}
}
您的树是否有任何可预测/可利用的结构?也就是说,您可以根据任何规则判断实体是位于左子树还是右子树中吗?如果没有,您将没有机会,但需要对您的树进行完整遍历,查找查找要查找的节点的位置。是的,我应该包括这一点,节点将具有id,因此在上面的示例中,它将是Boss(1)、Manager1(2)、manager2(3),并且控制2是1的左子节点和3是1的右子节点的规则是什么?很明显,这并不是通常的不平等关系。也许会有帮助。我们可以尝试通过添加到节点父节点来稍微加快进程。然后,找到管理器之间路径的最佳方法是找到第一个公共祖先(这可以在logn中完成-只需创建从根到manager1的完整路径,然后创建从根到manager2的完整路径,然后查找最后一个公共节点)。然后,您只需打印从Manager1到祖先,以及从祖先到Manager2的路径。我相信需要对树进行完整的遍历。您有权使用任何代码示例来说明如何执行此操作吗?感谢完整树遍历的两个主要选择是深度优先搜索和广度优先搜索。您应该可以找到许多使用这些术语的解释和代码示例。您的情况有点特殊,因为您需要记住每个节点的路径,但这是可行的。此代码可以很好地查找位于路径b/w 2节点上的所有节点。我将尝试进一步优化它,并将再次发布。