7

Assume we have a sequence of $0$s and $1$s: $n_1, n_2, ..., n_N$, in which $0$ stands for a leaf node, and $1$ stands for an uncertain node that may or may not be a leaf node. How can we check if this sequence is a valid result of a binary-tree preorder traversal?

Ex. $1, 1, 0, 1, 1, 0, 0, 1$ is a valid sequence.

          1
         / \
        1   1
       /   / \
      0   1   1
         / \   
        0   0
John L.
  • 39,205
  • 4
  • 34
  • 93
Harold H.
  • 71
  • 3

2 Answers2

1

The idea of construction in fade2black's answer is correct (while the pseudocode may be buggy). I rewrite it here:

FOR i = 2 to n:
  IF root.left is free:
    root.left = make_node(n[i])
    IF n[i] == 1:
      root = root.left 
  ELSE:
    # backtrack until root.right is free or we reach the ROOT - highest node
    WHILE root is not nil AND root.right is not free:
      root = root.parent  
    IF root is nil:
      RETURN failure
    root.right = make_node(n[i])
    IF n[i] == 1:
      root = root.right 

Its correctness can be proved by mathematical induction on $n$. Base cases are trivial.

Assume a sequence of length less than $n$ is valid if and only if a tree can be constructed by the algorithm. Now consider a sequence of length $n$.

If a tree can be constructed by the algorithm, the sequence is obviously valid.

On the other hand, if the sequence is valid, it must be $1, a_1,\ldots,a_p, b_1,\ldots,b_q$ where $a_1,\ldots, a_p$ and $b_1,\ldots,b_q$ are both valid sequences ($p$ or $q$ may be 0). By inductive assumption, the algorithm can construct a tree as the left subtree of the root from $a_1,\ldots,a_p$. Then the algorithm is handling $b_1$. Note the right child of the root is free, so the algorithm will not return "failure" during backtracking and successfully constructs $b_1$. By inductive assumption again, the algorithm sequentially constructs a subtree from $b_1,\ldots,b_q$. As a result, a tree is successfully constructed from the sequence $1,a_1,\ldots,a_p,b_1,\ldots,b_q$.

xskxzr
  • 7,613
  • 5
  • 24
  • 47
0

Idea of a tree construction

If the length of the sequence is $1$ then just make the first symbol root and stop with SUCCESS. If the first symbol of the sequence is $0$ then construction is not possible, otherwise make it the ROOT and set the root to the ROOT.

for i = 2 to n
 if n[i] is 1 then
   if root.left is free 
     root.left = make_node(n[i])
     root = root.left #go to left
   else if root.right is free then      
     root.right = make_node(n[i])
     root = root.right #go to right
   else
     # backtrack until root.right is free or we reach the ROOT - highest node
     root = root.parent until root is nil OR root.right is free
   end
 else if n[i] is 0 then
   if root.left is free 
     root.left = make_node(n[i])
   else if root.right is free
     root.right = make_node(n[i])  
   else
     # backtrack until root.right is free or we reach the ROOT - highest node
     root = root.parent until root is nil OR root.right is free
   end
 end

 if root is nil then break
end

if i < n the construction impossible

Checking without a tree construction

The basic idea is at each step to count how many nodes we can add to the tree. When we read $1$, we add one internal node which allows to add two new nodes and hence $-1+2 = 1$ and so we increment the counter by one. When we read $0$ we add a new leaf and so we decrement the counter.

if a[0] == 0 then 
  return FAILURE
else
  counter = 2

for i=2 to n
  if a[i] == 1 then
    counter = counter + 1 
  else
    counter = counter - 1
  end

  if counter == 0 then break  
end

if i < n then 
  return FAILURE
else
  return SUCCESS
end  

Construction example

$1,1,0,1,1,0,0,1$

  1 =>  1  => 1  => ... =>  1
       /     /             /
      1     1             1
           / \           / \
          0   1         0   1
                           / \
                          1   1
                         / \
                        0   0

Checking example

c=2, c=3, c=2,c=3, c=4, c=3, c=2, c=3, SUCCESS

At the end c=3 means we still can add 3 leaves.

fade2black
  • 9,905
  • 2
  • 26
  • 36