如何获取从根到二叉树上给定节点的路径?

时间:2011-09-09 00:26:43

标签: tree binary-tree

我试图找出如何从二进制树上获取从root到给定节点的路径。

它不是二叉搜索树。

每个非叶子节点只有两个指向其子节点的指针。

按顺序,预订,订单后遍历不起作用。

我曾尝试过预订,但无法弄清楚如何。例如,我们有一个二叉树: 它不是二叉搜索树。我们使用排序顺序节点来更容易地找到路径。

     1 
   /   \
  2     3
 / \   / \
4   5 6   7 

我们希望找到1到7之间的路径:

预订时,我们有:

1 -> 2 -> 4 -> 5 -> 3 -> 6 -> 7 

从流程中,我们得到1 - >的路径。 7上有所有节点。

显然,它不应该。

非常感谢任何帮助。

5 个答案:

答案 0 :(得分:27)

预先遍历,也称为深度优先搜索 工作。

  • 如果以递归方式实现前序遍历,那么当到达所需节点时,您可以展开堆栈(递归调用)并反向构建路径。

  • 如果您以非递归方式实施前序遍历,那么您将直接构建一个堆栈,因此在这种情况下,一旦到达所需的节点,您就已经拥有了路径。

在上面问题的树中,查找从1到7的路径的算法如下:

  • 从1开始,将其推入堆栈,堆栈现在为[1]
  • 向左移动到2,将其推入堆叠,现在堆​​叠为[1 2]
  • 左转到4,推它,叠加现在[1 2 4]
  • 没有4岁的孩子,这不是你想要的,所以弹出它,叠现在[1 2]
  • 现在你回到了2,你已经离开了,现在走吧,堆栈现在是[1 2 5]
  • 没有5岁的孩子,所以pop,stack现在是[1 2]
  • 你已经筋疲力尽2的孩子,所以弹出它,堆栈现在[1]
  • 现在你回到了1,你已经完成了左边,所以右转到3,推它,叠加现在[1 3]
  • 向左走,堆叠现在是[1 3 6]
  • 6是一片叶子,不是你要找的东西,所以pop,stack是[1 3]
  • 现在你必须从3开始向右推,现在叠加[1 3 7]
  • 但等待!看!您已到达所需的节点!看看你的筹码!这是你想要的道路。

答案 1 :(得分:6)

您将获得一个二叉树(根节点)..并且会给出一个键,该键可能在树中,也可能不在树中。 您必须找到从根到节点的完整路径。

示例:

                A
           /           \
       B                C
         \               /
          D           E
        /    \           \
      K      L        M
    /
Z

您已经给出了节点Z(或节点的密钥)和给定的节点A(根) 所以你的输出应该是

A B D K Z

如果给出M,则输出应为 A C E M

public class main_class {
public static void main(String args[] ) {

    //first create tree
    Node rootNode = new Node ('A' , new Node('B',null,
                                             new Node('D',
                                                      new Node('K',
                                                               new Node('Z',null,
                                                               null),null),
                                                      new Node('L',null,null))),
                                    new Node('C',
                                             new Node('E',
                                                      null,
                                                      new Node('M',null,null)),null) );

    ArrayList <Node> path = new ArrayList<Node>();
    System.out.println(getPath(rootNode,'Z',path));
    System.out.println(path);
    path = new ArrayList<Node>();
    System.out.println(getPath(rootNode,'M',path));
    System.out.println(path);

}
static boolean getPath(Node rootNode, char key, ArrayList<Node> path ){
    //return true if the node is found
    if( rootNode==null)
        return false;
    if (rootNode.getVal()==key){
        path.add(rootNode);
        return true;
    }
    boolean left_check = getPath( rootNode.left,key,path);
    boolean right_check = getPath( rootNode.right,key,path);
    if ( left_check || right_check){
        path.add(rootNode);
        return true;
    }
    return false;

}
static class Node {
    char val;
    Node left;
    Node right;
    public Node( char val, Node left, Node right){
        this.left=left;
        this.right=right;
        this.val=val;
    }
    public char getVal(){
        return val;
    }
   public String toString(){
        return " " + val + " ";
    }
}

}

答案 2 :(得分:1)

考虑以下树:

       10
     /   \
    8      2
  /  \    /
3     5  2

方法

  • 我们从根开始并将其与密钥进行比较,如果匹配则打印路径(如果树只有一个节点,则路径只包含根)。
  • 否则将节点推入Vector(我认为用于存储路径的向量)。
  • 递归地向左和向右走。

以下代码将有所帮助:

     void PrintPath(node* root, vector <int> v,int key)
     {
      if(!root)
      return;
      if(root->data==key)
        {
          v.push_back(root->data);
          vector<int>:: iterator it;
          for(it=v.begin();it<v.end();it++)
           {
             cout<<*it<<" ";
           }
            return;
        }
        v.push_back(root->data);
        PrintPath(root->left,v,key);
        PrintPath(root->right,v,key);
    }    

<强>解释

让找到的节点为给定树的5(密钥)。

每一步的载体内容:

  1. V = 10
  2. V = 10,8
  3. V = 10,8,3(3不是找到的关键,所以我们将回溯并向右转)
  4. V = 10,8,5(因此打印路径为5键)。

答案 3 :(得分:0)

Java中有3个解决方案:
https://codereview.stackexchange.com/questions/105136/path-sum-in-binary-tree
首先是递归方法,第二个是使用2个satcks,最后一个是使用2个队列。希望这有帮助

答案 4 :(得分:-1)

public List<Node<T>> getPath(T data){
        Stack<Node<T>> stack = new Stack<Node<T>>();
        Boolean found =  getPath(root, stack, data);
        List<Node<T>> path = new ArrayList<Node<T>>();

        if(!found){
            return path;
        }
        return Arrays.asList(stack.toArray((Node<T>[])new Node[stack.size()]));
    }

    public Boolean getPath(Node<T> node, Stack<Node<T>> stack, T data){
        if(node == null){
            return false;
        }
        stack.push(node);

        if(node.data.equals(data)){
            return true;
        }
        Boolean found = getPath(node.left, stack, data) ||
                getPath(node.right, stack, data);

        if(!found ){
            stack.pop();
        }
        return found;
    }