繁体   English   中英

构造具有预先遍历遍历的树

[英]Construct tree with pre-order traversal given

给出一种特殊类型的树,其中所有叶子用L标记,而其他叶子用N标记。 每个节点可以有0个或最多2个节点。 给出了树的前序遍历。

给出一个算法来从这个遍历构建树。

这是预订序遍历算法:

Preorder(T)
  if (T is not null)
    print T.label
    Preorder(T.left)
    Preorder(T.right)

让我们试着找一个NNLLNL输入的NNLLNL

显然,首先打印根标签。 所以你知道root有标签N 现在算法在左子树上进行递归。 根据输入,这也是N 递归左边的子树,即L 现在你必须回溯,因为你已经到了一片叶子。 输入中的下一个位置也是L ,因此当前节点有一个标有L的右子节点。 回溯一次。 再次回溯,因为您已添加当前节点的所有子节点(最多2个子节点)。 现在你又回到了原点。 你必须走对,因为你已经离开了。 根据输入,这是N 所以根的正确孩子是N 左边的孩子是L 这是你的树:

       N
     /   \
    N     N
   / \   /
  L   L L

请注意,解决方案不一定是唯一的,但这将为您提供可能的解决方案。

伪代码:

k = 0
input = ... get preorder traversal vector from user ...
Reconstruct(T)
  if input[k] == N
    T = new node with label N
    k = k + 1 
    Reconstruct(T.left)
    Reconstruct(T.right)
  else 
    T = new node with label L
    T.left = T.right = null
    k = k + 1

使用空节点调用。

后续问题 :给定包含不同节点标签的二叉树的预订和顺序遍历,您如何才能唯一地重建树?

这是我的golang版本,用于解决leetcode中有关树的许多问题。

// NewPreorderTree returns preorder tree relate to nums, nums must has not Ambiguity.
// -1 in nums represents child is null.
//
// Example 1:
//  Input: [1, 2, 3]
//  Generate:
//          1
//         /
//        2
//       /
//      3
//
// Example 2:
//  Input: [1, 2, -1, -1, 3] or [1, 2, -1, -1, 3, -1, -1]
//  Generate:
//         1
//        / \
//       2   3
func NewPreorderTree(nums ...int) *TreeNode {
    return (&preorderTree{nums}).constructTree()
}

type preorderTree struct {
    nums []int
}

func (p *preorderTree) constructTree() *TreeNode {
    if len(p.nums) == 0 {
        return nil
    }

    if p.nums[0] == -1 {
        p.nums = p.nums[1:]
        return nil
    }

    root := &TreeNode{Val: p.nums[0]}
    p.nums = p.nums[1:]
    root.Left = p.constructTree()
    root.Right = p.constructTree()
    return root
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM