Binary tree from Preorder and inorder traversal

后端 未结 3 1854
小蘑菇
小蘑菇 2021-01-07 05:37

How can I get the tree form these pre/in order traversal:

Pre: A,B,D,E,C,F,G,H in:E,D,B,A,G,F,H,C

EDITED: MY Answer

       A         


        
相关标签:
3条回答
  • 2021-01-07 06:12

    EDIT: Correction,

    You don't have the correct answer, FGH is to the left of C.

    To verify just run the two algorithms against it:

    PreOrder(node)
      if node is null return
      Print(node)
      PreOrder(node.left)
      PreOrder(node.Right)
    
    InOrder(node)
      if node is null return
      InOrder(node.left)
      Print(node)
      InOrder(node.Right)
    

    You know that A is the root because it starts the pre-order. Use the in-order to arrange nodes to the left and right of A. B is the second node (pre-order), and left of A (in-order), and so on.

    You know that F,G,H is left of C because of the in-order arrangement.

    Basically, use preorder to select the next node, and in-order to see whether it is left or right of the parent node.

    EDIT (18 Apr 2011):

    To show how mechanical the process is I offer this pseudo code:

    // Add method on binary tree class -- stock standard
    method Add(item, comparer)
      newNode = new Node(item)
      parent = null
    
      // Find suitable parent
      currentNode = root
      while currentNode is not null
        parent = currentNode
        if comparer(newNode.Key, currentNode.Key) < 0
          currentNode = currentNode.Left
        else 
          currentNode = currentNode.Right
    
      // Add new node to parent
      if parent is null
        root = newNode
      else if comparer(newNode.Value, parent.Value) < 0 
        parent.Left = newNode
      else 
        parent.Right = newNode
    

    The trick is to use the in-order sequence to determine whether a node is added to the left or right of its parent, for example:

    // Client code
    // Input arrays
    var preOrder = ["A","B","D","E","C","F","G","H"]
    var inOrder  = ["E","D","B","A","G","F","H","C"]
    // A collection associating the Key value with its position in the inOrder array
    var inOrderMap = GetInOrderMap(inOrder)
    
    // Build tree from pre-order and in-order sequences
    foreach (item in preOrder) 
      Add(item, fun (l, r) -> inOrderMap[l] - inOrderMap[r])
    

    I'm passing a lamba, but any equivalent method for passing a comparer should do.

    0 讨论(0)
  • 2021-01-07 06:30

    Below is a working implementation in C#

    public static class TreeUtil
    {
       public static BinarySearchTree<T> FromTraversals<T>(T[] preorder, T[] inorder)
       {
           if (preorder == null) throw new ArgumentNullException("preorder");
           if (inorder == null) throw new ArgumentNullException("inorder");
           if (preorder.Length != inorder.Length) throw new ArgumentException("inorder and preorder have different lengths");
    
           int n = preorder.Length;
           return new BinarySearchTree<T>(FromTraversals(preorder, 0, n - 1, inorder, 0, n - 1));
       }
    
       public static BinaryTreeNode<T> FromTraversals<T>(T[] preorder, int pstart, int pend, T[] inorder, int istart, int iend)
       {
           if (pstart > pend) return null;
    
           T rootVal = preorder[pstart];
           int rootInPos;
           for (rootInPos = istart; rootInPos <= iend; rootInPos++) //find rootVal in inorder
               if (Comparer<T>.Default.Compare(inorder[rootInPos], rootVal) == 0) break;
    
           if (rootInPos > iend)
               throw new ArgumentException("invalid inorder and preorder inputs");
    
           int offset = rootInPos - istart;
           return new BinaryTreeNode<T>(rootVal)
               {
                   Left = FromTraversals(preorder, pstart + 1, pstart + offset, inorder, istart, istart + offset - 1),
                   Right = FromTraversals(preorder, pstart + offset + 1, pend, inorder, istart + offset + 1, iend),
               };
       }
    }
    

    Here is one possible implementation of BinarySearchTree<T> and BinaryTreeNode<T>. Some tests:

    [TestMethod]
    public void TestGenerationFromTraversals()
    {
      var preorder = new[] {1, 2, 4, 5, 3};
      var inorder = new[] {4, 2, 5, 1, 3};
      AssertGenerationFromTraversal(preorder, inorder);
    
      var preorder2 = new[] { 'A', 'B', 'D', 'E', 'C', 'F' };
      var inorder2 = new[] { 'D', 'B', 'E', 'A', 'F', 'C' };
      AssertGenerationFromTraversal(preorder2, inorder2);
    }
    
    private static void AssertGenerationFromTraversal<T>(T[] preorder, T[] inorder)
    {
      var tree = BinarySearchTreeUtil.FromTraversals(preorder, inorder);
    
      var treeInorder = new List<T>();
      tree.TraverseInOrder(treeInorder.Add);
      var treePre = new List<T>();
      tree.TraversePreOrder(treePre.Add);
    
      Assert.IsTrue(preorder.SequenceEqual(treePre));
      Assert.IsTrue(inorder.SequenceEqual(treeInorder));
    }
    
    0 讨论(0)
  • 2021-01-07 06:34

    Here is a mathematical approach to achieve the thing in a very simplistic way :

    Language Used : Java

    `
    /* Algorithm for constructing binary tree from given Inorder and Preorder traversals. Following is the terminology used :

    i : represents the inorder array supplied

    p : represents the preorder array supplied

    beg1 : starting index of inorder array

    beg2 : starting index of preorder array

    end1 : ending index of inorder array

    end2 : ending index of preorder array

    */

    public static void constructTree(Node root, int[] i, int[] p, int beg1, int end1, int beg2, int end2)

    {

    if(beg1==end1 && beg2 == end2)
    {
        root.data = i[beg1];
    }
    else if(beg1<=end1 && beg2<=end2)
    {
        root.data = p[beg2];
        int mid = search(i, (int) root.data);
        root.left=new Node();
        root.right=new Node();
        constructTree(root.left, i, p, beg1, mid-1, beg2+1, beg2+mid-beg1);
        System.out.println("Printing root left : " + root.left.data);
        constructTree(root.right, i, p, mid+1, end1, beg2+1+mid-beg1, end2);
        System.out.println("Printing root left : " + root.right.data);
    }
    

    }

    `

    You need invoke the function by following code :

    int[] i ={4,8,7,9,2,5,1,6,19,3,18,10}; //Inorder
    int[] p ={1,2,4,7,8,9,5,3,6,19,10,18}; //Preorder
    Node root1=new Node();
    constructTree(root1, i, p, 0, i.length-1, 0, p.length-1);
    

    In case you need a more elaborate explanation of code please mention it in the comments. I would be happy to help :).

    0 讨论(0)
提交回复
热议问题