Search code examples
algorithmtreetree-traversalpreorder

How to remove children of tree nodes with single child


I have an array for pre-order traversal of a tree (node values are depth values). All I want to do is to minimize tree by removing the children of internal nodes having only one child.

As an example (a tree with max depth = 3) problem visualized here

Input array: [0, 1, 2, 3, 3, 1, 2, 3]
Output array: [0, 1, 2, 2, 1]

How should be the algorithm?


Solution

  • A simple O(nlog(n)) average-case algorithm arises from attacking the problem by divide-and-conquer approach.

    Start with input_level = 0, output_level=0, left=0, right=n-1.

    In each of the recursive steps, count the elements with value input_level+1 in the input array A in range [left, right]. These are the children of the current node. If there are no such elements, print output_level and return. If there is just one such element, "delete" the current node (i.e. do not print it), increase left by 1, and call the function recursively. If there are two or more such elements, print output_level, increase output_level by 1, and apply the function recursively to each of the intervals demarcated by the children elements. Always increase input_level when doing the recursive call.

    For the example input A=[0, 1, 2, 3, 3, 1, 2, 3], first the algorithm would find elements with value 1, at indexes 1 and 5. Then it would print 0, increase output_level and current_level by 1, and call itself recursively two times: on ranges [1, 4] and [5, 7].

    The complexity of this is O(n2) in the worst case (for the degenerate tree that is in fact a list), but O(nlog(n)) on the average, as a random n-ary tree has height O(log(n)).