Java 在二叉树中查找两个节点之间的路径

Java 在二叉树中查找两个节点之间的路径,java,data-structures,binary-tree,nodes,args,Java,Data Structures,Binary Tree,Nodes,Args,我有以下简单的树: 我的目标是找到两个管理器节点之间的路径 这两个节点将在cmd中选择输入 因此,用户可能会键入“java BinaryTree manager1 manager2”,输出将显示到达第二个管理器所需的路径。此示例应输出以下内容: 'Manager1>Boss

我有以下简单的树:

我的目标是找到两个管理器节点之间的路径

这两个节点将在cmd中选择输入

因此,用户可能会键入“java BinaryTree manager1 manager2”,输出将显示到达第二个管理器所需的路径。此示例应输出以下内容:

'Manager1>Boss 到目前为止,我的代码定义了节点,但是我需要一个findPath方法来打印路径

代码:`

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节点上的所有节点。我将尝试进一步优化它,并将再次发布。