【问题标题】:- Binary Tree Puzzle - Draw tree from these traversals:- 二叉树拼图 - 从这些遍历中绘制树:
【发布时间】:2015-10-31 01:18:07
【问题描述】:

顺序:S A E U Y Q R P D F K L M

预购:F A S Q Y E U P R D K L M

我很困惑如何处理中间部分。似乎没有任何组合有效,帮助?有人有窍门吗?我该如何处理?我已经为此苦恼了 2 个小时。

我必须恢复这棵树。

【问题讨论】:

  • 在给定前序和中序遍历的情况下,你想要恢复树吗?
  • 基本上是的。我找不到树的其余部分。

标签: tree binary-tree inorder preorder


【解决方案1】:

正确的结果是

我将尝试为您提供一般性的解释,而不是为您的示例提供具体的解释。我认为它更有用,毕竟你可以用你的具体案例测试算法,看看算法是否有效并更好地理解。

你可以用递归的方式思考这个问题。

为了解决问题,我们可以在一些变量上达成一致

  • preorder: 包含前序遍历的数组
  • inorder: 包含中序遍历的数组
  • l_ppreorder 数组中的左索引
  • r_ppreorder 数组中的右索引
  • l_iinorder 数组中的左索引
  • r_iinorder 数组中的右索引

在您的具体示例中,第一个实例是 l_p = l_i = 0r_p = r_i = 12

这样可以方便解释:

index     0 1 2 3 4 5 6 7 8 9 10 11 12
preorder: F A S Q Y E U P R D  K  L  M
inorder:  S A E U Y Q R P D F  K  L  M
          <      left     > ^   < right >
                            |
                      this is the root

一个非常重要的事实是要意识到当前树的根总是preorder[l_p],第一次是F。现在,您必须识别树的左右分支,它们在inorder 数组中被清楚地区分(见上图)。为了知道这一点,您在inorder 数组中搜索包含根F 的索引;这个索引是9。我们可以看到根在l_i 之后的九个位置。让i 一个变量表示相对于l_i 的位置是树的根。

所以,左树的键在inorder数组08之间,右树的键在1012之间。

为了递归地构建左树,你有l_p = l_p + 1,因为你已经看到了根和r_ p = l_p + i =,但是数组inorderl_i = 0r_i = l_i + i - 1 =8分隔。

同理,右树在preorder中,在l_p = l_p + i + 1 = 10r_p = r_p = 12之间,而在数组inorder中,它在l_i = l_i + i + 1r_i之间。

有了这一切(有点复杂),我们可以勾勒出一个算法:

Node * build_tree(int preorder[], int l_p, int r_p,
                  int inorder[], int l_i, int r_i)
{
  if (l_p > r_p)
    return nullptr; // empty tree

  Node * root = new Node;
  root->key = preorder[l_p];

  int i = 0; // now we search index of preorder[l_p] in inorder array
  for (int j = l_i; j <= r_i; ++j)
    if (inorder[j] == preorder[l_p])
      {
        i = j - l_i; // the root is at l_i + i
        break; // always breaks if everything is ok
      }

  root->left = build_tree(preorder, l_p + 1, l_p + i, 
                          inorder, l_i, l_i + (i - 1));
  root->right = build_tree(preorder, l_p + i + 1, r_p, 
                           inorder, l_i + i + 1, r_i);
  return root;
}

【讨论】:

  • 非常感谢! :) 这是一个了不起的答案。
猜你喜欢
  • 2012-01-01
  • 2022-11-11
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-08
相关资源
最近更新 更多