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

Tree 如何在二叉树上获得从根到给定节点的路径?,tree,binary-tree,Tree,Binary Tree,我试图找出如何在二叉树上获得从根到给定节点的路径 它不是二进制搜索树 每个非叶节点只有两个指向其子节点的指针 顺序、预顺序、后顺序遍历不起作用 我试着做预订单,但不知道怎么做。例如,我们有一个二叉树: 它不是一个二进制搜索树。我们使用排序顺序节点使查找路径更容易 1 / \ 2 3 / \ / \ 4 5 6 7 我们希望找到从1到7的路径: 通过预购,我们有: 1 -> 2 -> 4 -> 5 -> 3 -> 6

我试图找出如何在二叉树上获得从根到给定节点的路径

它不是二进制搜索树

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

顺序、预顺序、后顺序遍历不起作用

我试着做预订单,但不知道怎么做。例如,我们有一个二叉树: 它不是一个二进制搜索树。我们使用排序顺序节点使查找路径更容易

     1 
   /   \
  2     3
 / \   / \
4   5 6   7 
我们希望找到从1到7的路径:

通过预购,我们有:

1 -> 2 -> 4 -> 5 -> 3 -> 6 -> 7 
从这个流中,我们得到了1->7的路径,所有节点都在上面

显然,这不应该


非常感谢您的帮助。

预序遍历,也就是所谓的深度优先搜索确实有效

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

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

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

  • 从1开始,将其推到堆栈上,堆栈现在为[1]
  • 向左走到2,将其推到堆栈上,堆栈现在为[12]
  • 向左走到4号,按它,堆栈现在是[1 2 4]
  • 这里没有4个孩子,这不是你想要的,所以弹出它,堆栈现在是[12]
  • 现在您回到2,并且已经向左走了,现在向右走,堆栈现在是[1 2 5]
  • 没有5岁的孩子,所以pop,stack现在是[12]
  • 你已经耗尽了2个孩子的能量,所以弹出它,堆栈现在是[1]
  • 现在你回到1,你已经完成了左边,所以向右走到3,推它,堆栈现在是[13]
  • 向左走,堆栈现在是[1 3 6]
  • 6是一片叶子,不是你要找的,所以pop,stack是[13]
  • 现在你必须从3向右推,堆栈现在是[1 3 7]
  • 但是等等!看!您已到达要查找的节点!看看你的书堆!这是你想要的路

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

      例如:

                      A
                 /           \
             B                C
               \               /
                D           E
              /    \           \
            K      L        M
          /
      Z
      
      您已经指定了节点Z(或节点的键)和节点A(根) 所以你的输出应该是

      A B D K Z

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

      公共类主类{
      公共静态void main(字符串参数[]){
      //首先创建树
      Node rootNode=新节点('A',新节点('B',null,
      新节点('D',
      新节点('K',
      新节点('Z',空,
      空),空),
      新节点('L',null,null)),
      新节点('C',
      新节点('E',
      无效的
      新节点('M',null,null)),null));
      ArrayList路径=新建ArrayList();
      System.out.println(getPath(rootNode,'Z',path));
      System.out.println(路径);
      路径=新的ArrayList();
      System.out.println(getPath(rootNode,'M',path));
      System.out.println(路径);
      }
      静态布尔getPath(节点根节点、字符键、ArrayList路径){
      //如果找到节点,则返回true
      if(rootNode==null)
      返回false;
      if(rootNode.getVal()==键){
      add(rootNode);
      返回true;
      }
      布尔left\u check=getPath(rootNode.left,key,path);
      布尔右键检查=getPath(rootNode.right,key,path);
      如果(左检查| |右检查){
      add(rootNode);
      返回true;
      }
      返回false;
      }
      静态类节点{
      char-val;
      左淋巴结;
      节点权;
      公共节点(字符值、左节点、右节点){
      这个。左=左;
      这个。右=右;
      这个.val=val;
      }
      公共字符getVal(){
      返回val;
      }
      公共字符串toString(){
      返回“+val+”;
      }
      }
      }
      
      公共列表getPath(T数据){
      堆栈=新堆栈();
      Boolean found=getPath(根、堆栈、数据);
      列表路径=新的ArrayList();
      如果(!找到){
      返回路径;
      }
      返回Arrays.asList(stack.toArray((Node[])新节点[stack.size()]);
      }
      公共布尔getPath(节点、堆栈、T数据){
      if(node==null){
      返回false;
      }
      栈推(节点);
      if(node.data.equals(data)){
      返回true;
      }
      Boolean found=getPath(node.left、stack、data)||
      getPath(node.right、堆栈、数据);
      如果(!找到){
      stack.pop();
      }
      发现退货;
      }
      
      考虑以下树:

             10
           /   \
          8      2
        /  \    /
      3     5  2
      
      方法

      • 我们从根开始,将其与键进行比较,如果匹配,则打印路径(如果树只有一个节点,则路径仅包含根)
      • 否则,将节点推入Vector(我认为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);
          }    
      
      void打印路径(节点*根,向量v,int键)
      {
      如果(!root)
      返回;
      如果(根->数据==键)
      {
      v、 向后推(根->数据);
      向量::迭代器;
      
      对于(it=v.begin();it在Java中有3种解决方案:

      第一种是递归方法,第二种是使用2个satck,最后一种是使用2个队列。希望这对我有所帮助
             10
           /   \
          8      2
        /  \    /
      3     5  2
      
           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);
          }