Бинарное дерево: как я могу реализовать LCA с одним узлом?

Я пытаюсь сделать это прямо сейчас, используя рекурсию, но мне трудно, я думаю, что у меня есть логическая ошибка.

пожалуйста, помогите мне кто-нибудь Т_Т

Вот мой код до сих пор

    import java.util.ArrayList;
    public class BTNode{
        private BTNode root, left,right;
        private int item;

    public BTNode(int item){
        this(item,null,null,null);
    }
    public BTNode(int item, BTNode left, BTNode right, BTNode root,int count){
        this.item = item;
        this.left = left;
        this.right = right;
        this.root = root;
      this.count=count;
    }
    public void build(){
        this.left = new BTNode(40);
        this.left.root = this;

        this.right = new BTNode(100);
        this.right.root = this;

        this.left.right = new BTNode(45);
        this.left.right.root = this.left;

        this.left.left = new BTNode(25);
        this.left.left.root = this.left;

        this.right.left = new BTNode(70);
        this.right.left.root = this.right;

        this.right.right = new BTNode(200);
        this.right.right.root = this.right;

    }
    public void inorder(){//recursion
        //traverse the left
        if(left != null)
            left.inorder();
        //visit the root do the item
        System.out.print(this.item+" ");
        //traverse the right
        if(right != null)
            right.inorder();
    }
    public String inToString(){
        return ((left == null)?"": left.inToString()) + item + " " + ((right == null)?"": right.inToString()+" ");
    }
    //preorder()
    public void  preorder(){

      //visit the root do the item
        System.out.print(this.item+" ");
      //traverse the left
        if(left != null)
            left.preorder();
        //traverse the right
        if(right != null)
            right.preorder();
    }
   //preToString()
    public String preToString(){
        return item+ " "+((left == null)?"": left.preToString())+ ((right == null)?"": right.preToString()+" ");
    }
    //postorder()
   public void  postorder(){
        //traverse the left
        if(left != null)
            left.postorder();
        //traverse the right
        if(right != null)
            right.postorder();
      //visit root do the item
      System.out.print(this.item+" ");

    }
   //postToString()
    public String postToString(){
        return ((left == null)?"": left.postToString()) + ((right == null)?"": right.postToString()+" ")+item+ " ";
    }



    //findsum-recursive
   public int findsum(){
      //traverse left,if null traverse to right then add the two item lastly add to the root
       return ((left == null)?0: left.findsum()) + ((right == null)?0: right.findsum())+item;
   }




    //findlevel-recursive
   public int findlevel(){
      //check left && right if it is not null then iterate method recursively
      if (left == null)
                return 0;
      else if(right == null)
            return 0;
      else
          return 1 + left.findlevel();
  }
  /*
    //ancestor-recursive
   public BTNode ancestor(int value){
      if(left.count== 2){//check the root
         return left.ancestor();//traverse left node
      }
      System.out.print(item+" ");//print item if the left turns false
      if(root != null){
         right.ancestor();//traverse right node
      }
   }*/



   public int count(){
      //check if left || right are null then return 0, otherwise method were recursively executed
      return (((left==null)?0:1+left.count())+((right==null)?0:1+right.count()));
   }

   public void reference(){
      //check left != null print the root, traverse left, traverse right
      if(left != null)
         left.reference();
      if(left != null)
         System.out.print(item+" ");
      if(right != null)
         right.reference();

   }
   public void sort(){

   }
   public void insert(int given){
      BTNode node = new BTNode(given);

      if(item == 0)
         root = node;
      else
         {
            BTNode current = root; //points to the current Node
            BTNode parent; //points to the parent Node

            while(current != null)
            {
               if(item > given)
               {
                  parent = current;
                  current = left;
               }

               if(item < given)
               {
                  parent = current;
                  current = right;
               }
            }
            current = node;
            if(item < given)
               right = node;
            else
               left = node;
         }
        right.inorder();
   }
   public boolean contains(int given){
         return ((left==null)?false:left.contains(given))|| item==given || ((right == null)?false : right.contains(given));
         /*if(left != null)
            left.contains(given);
         if(right != null)
            right.contains(given);
         return item == given;*/
   }
    public static void main(String[]args){
        BTNode root = new BTNode(50);

        root.build();
        System.out.print("\nGiven :"+root.inToString());
        System.out.println("\ninorder");
        root.inorder();
        System.out.println("\npreorder");
        root.preorder();
      System.out.println("\npostorder");
        root.postorder();
      System.out.println("\nfindsum");
      System.out.println(root.findsum());
      System.out.println("\nfindlevel");
      //System.out.println(root.findlevel(200));
      System.out.println(root.findlevel());
      System.out.println("\nancestor");
      //System.out.println(root.ancestor());
      root.ancestor();
      System.out.println("\ncount");
      System.out.println(root.count());

      System.out.println("\nreference");
      //System.out.println(root.reference());
      root.reference();
      System.out.println("\nsort");
      //System.out.print(root.sort());
      root.sort();
      System.out.println("\nContains");
      System.out.println(root.contains(new Integer(70)));
      System.out.println("\ninsert");
      //System.out.print(root.sort());
      root.insert(new Integer(71));
          root.printinorder();
   }
}

Пожалуйста, также проверьте мой механизм вставки... Я не думаю, что это правильный способ сделать это


person Amits    schedule 12.03.2017    source источник
comment
или, может быть, дайте мне несколько ваших советов... Пожалуйста   -  person Amits    schedule 12.03.2017
comment
пожалуйста, добавьте больше объяснений вашей логики и почему вы это сделали, а также чего именно вы пытаетесь достичь.   -  person Dev2017    schedule 12.03.2017
comment
Привет!! @DanishAlsayed, как мне реализовать код для поиска наименьшего общего предка моего двоичного дерева? учитывая только один узел... например, root.ancestor(25)... тогда вывод будет 50 в рекурсивном   -  person Amits    schedule 12.03.2017
comment
вы можете уточнить больше? Чей предок? Корни не имеют предков. Или вы имеете в виду, что для узла в дереве вы хотите найти наименьшего предка? Что вы подразумеваете под общим, общим должно быть более одного узла. Взгляните на этот stackoverflow.com/ вопросы/12085869/   -  person Dev2017    schedule 12.03.2017
comment
@DanishAlsayed Прошу прощения ... да, это именно то, что я имею в виду ... но учитывая только один узел ... (20 40 45 50 70 100 200 в порядке), например, предок (25) = 50, а не предок (25,70) = 50. .. угу, я ужасно объясняю, мне так жаль   -  person Amits    schedule 12.03.2017
comment
вы хотите предшественника или предка? Более того, 25 не существует в показанном вами дереве. Если вы имеете в виду предшественника, то в порядке сортировки дерево сортируется по возрастанию, поэтому ответом является узел прямо перед рассматриваемым.   -  person Dev2017    schedule 12.03.2017
comment
@DanishAlsayed, мне очень жаль... в смысле (25 40 45 50 70 100 200 по порядку)   -  person Amits    schedule 12.03.2017
comment
так вы имеете в виду минимального предка данной пары узлов?   -  person Dev2017    schedule 12.03.2017
comment
@DanishAlsayed указан только один узел, а не пара   -  person Amits    schedule 12.03.2017
comment
Итак, учитывая узел, вам нужен минимальный предок?   -  person Dev2017    schedule 12.03.2017
comment
@DanishAlsayed да, именно так.. пожалуйста, помогите мне.. я не могу выкинуть это из головы   -  person Amits    schedule 12.03.2017


Ответы (1)


Поскольку ваш вопрос неясен, я отвечаю на оба ваших возможных вопроса.

1- Если вы хотите найти минимального предка узла, вы можете сделать так, чтобы узел продолжал перемещаться по своим родителям, сохраняя при этом отслеживание наименьшего найденного родительского значения. Как только вы достигнете корневого узла, у вас будет наименьшее значение. Временная сложность этого алгоритма составляет O(h), где h — высота дерева. Поскольку это очень просто, я не привожу здесь пример кода.

2- Если вы хотите найти LCA (это то, о чем вы задаете вопрос), вы можете сделать что-то очень похожее. Если мы предположим, что ключи n1 и n2 присутствуют в двоичном дереве, мы можем найти LCA, используя один обход двоичного дерева и без дополнительного хранилища для массивов путей. Идея состоит в том, чтобы пройти по дереву, начиная с корня. Если какой-либо из заданных ключей (n1 и n2) совпадает с корнем, то корнем является LCA (при условии, что присутствуют оба ключа). Если корень не совпадает ни с одним из ключей, мы повторяемся для левого и правого поддерева. Узел, у которого есть один ключ в левом поддереве, а другой ключ в правом поддереве, называется LCA. Если оба ключа лежат в левом поддереве, то и левое поддерево имеет LCA, иначе LCA лежит в правом поддереве. Вот пример кода, который вы можете настроить в соответствии с вашими потребностями (этот код работает):

//Java implementation to find lowest common ancestor of
// n1 and n2 using one traversal of binary tree

/* Class containing left and right child of current
 node and key value*/
class Node
{
    int data;
    Node left, right;

    public Node(int item)
    {
        data = item;
        left = right = null;
    }
}

public class BinaryTree
{
    //Root of the Binary Tree
    Node root;

    Node findLCA(int n1, int n2)
    {
        return findLCA(root, n1, n2);
    }

    // This function returns pointer to LCA of two given
    // values n1 and n2. This function assumes that n1 and
    // n2 are present in Binary Tree
    Node findLCA(Node node, int n1, int n2)
    {
        // Base case
        if (node == null)
            return null;

        // If either n1 or n2 matches with root's key, report
        // the presence by returning root (Note that if a key is
        // ancestor of other, then the ancestor key becomes LCA
        if (node.data == n1 || node.data == n2)
            return node;

        // Look for keys in left and right subtrees
        Node left_lca = findLCA(node.left, n1, n2);
        Node right_lca = findLCA(node.right, n1, n2);

        // If both of the above calls return Non-NULL, then one key
        // is present in once subtree and other is present in other,
        // So this node is the LCA
        if (left_lca!=null && right_lca!=null)
            return node;

        // Otherwise check if left subtree or right subtree is LCA
        return (left_lca != null) ? left_lca : right_lca;
    }

    /* Driver program to test above functions */
    public static void main(String args[])
    {
        BinaryTree tree = new BinaryTree();
        tree.root = new Node(1);
        tree.root.left = new Node(2);
        tree.root.right = new Node(3);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(5);
        tree.root.right.left = new Node(6);
        tree.root.right.right = new Node(7);
        System.out.println("LCA(4, 5) = " +
                            tree.findLCA(4, 5).data);
        System.out.println("LCA(4, 6) = " +
                            tree.findLCA(4, 6).data);
        System.out.println("LCA(3, 4) = " +
                            tree.findLCA(3, 4).data);
        System.out.println("LCA(2, 4) = " +
                            tree.findLCA(2, 4).data);
    }
}

Этот метод и код взяты с http://www.geeksforgeeks.org/lowest-common-ancestor-binary-tree-set-1/ на этом сайте вы можете запускать код как в среде IDE, так и онлайн.

person Waleed Zafar    schedule 13.03.2017