Подтвердить что ты не робот

Как получить путь от корня до заданного node на двоичном дереве?

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

Это не двоичное дерево поиска.

Каждый нелистный node имеет только два указателя на своих детей.

В порядке, предварительный заказ, послепорядок обход не работает.

Я пытался сделать предварительный заказ, но не могу понять, как это сделать. Например, у нас есть двоичное дерево: Это не двоичное дерево поиска. Мы используем порядок сортировки node, чтобы упростить поиск пути.

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

Мы хотим найти путь от 1 до 7:

С предварительным порядком мы имеем:

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

Из потока мы получаем путь от 1 → 7 со всеми узлами на нем.

Obviuosly, этого не должно быть.

Любая помощь действительно оценена.

4b9b3361

Ответ 1

Обход прерывания, иначе известный как поиск по глубине, действительно работает.

  • Если вы рекурсивно реализуете обход предлога, тогда, когда вы достигнете желаемого node, вы можете развернуть свой стек (из рекурсивных вызовов) и построить свой путь в обратном порядке.

  • Если вы реализуете обход предзаказов нерекурсивно, вы будете строить стек напрямую, поэтому в этом случае, когда вы достигнете желаемого node, у вас уже есть свой путь.

В дереве вашего вопроса выше алгоритм поиска пути от 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 is [1 3]
  • Теперь вам нужно перейти вправо от 3, нажать его, теперь стек [1 3 7]
  • Но ЖДИТЕ! СМОТРЕТЬ! Вы пришли к node, который вы ищете! И посмотри на свой стек! Это путь, который вы хотите.

Ответ 2

Вам предоставляется двоичное дерево (root Node).. и предоставляется ключ, который может быть или не быть в дереве. Вы должны найти полный путь от корня до node.

Пример:

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

вы указали node Z (или ключ для node) и заданы node A (root) Таким образом, ваш вывод должен быть

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 + " ";
    }
}

}

Ответ 3

Рассмотрим следующее дерево:

       10
     /   \
    8      2
  /  \    /
3     5  2

Подход

  • Мы начинаем с корня и сравниваем его с ключом, если они совпадают, а затем печатают путь (если дерево имеет только один node, то путь содержит только корень).
  • Else нажмите node в 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);
    }    

Объяснение

Пусть node будет найдено 5 (ключ) для данного дерева.

Содержание вектора на каждом шаге:

  • V = 10
  • V = 10,8
  • V = 10,8,3 (3 не является ключом к поиску, поэтому мы вернемся назад и идем вправо)
  • V = 10,8,5 (5 - это ключ, поэтому напечатайте путь).

Ответ 5

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;
    }