从inorder和preorder重构二叉树

时间:2017-03-24 04:12:05

标签: algorithm tree binary-tree

我正在尝试从:

构建二叉树

•预购:A B C D E F G H I J K L M
•按顺序:C E D F B A H J I K G M L

我几乎是肯定的,树的左半部分是正确的,但右半部分似乎不正确。

任何人都可以看出他们是否可以找出我的问题所在?

我知道预订是父母,左,右 那个顺序是左,父,右

我需要做些什么来确保这棵树是正确的?

Binary Tree

2 个答案:

答案 0 :(得分:1)

您可以在预订和按顺序遍历时应用以下算法。生成的树将始终有效且唯一。

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

TreeNode *treeBuilder(vector<int> &preorder, vector<int> &inorder, int start, int end, int indx) {
    if(start > end) return nullptr;

    TreeNode *root = new TreeNode(preorder[indx]);
    int rootPosition;    
    for(int i = start; i <= end; ++i) {
        if(inorder[i] == root->val) {
            rootPosition = i;
            break;
        }
    }
    root->left = treeBuilder(preorder, inorder, start, rootPosition - 1, indx + 1);
    root->right = treeBuilder(preorder, inorder, rootPosition + 1, end, indx + 1 + rootPosition - start);
    return root;
}

TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
    if(preorder.size() == 0) return nullptr;
    return treeBuilder(preorder, inorder, 0, inorder.size() - 1, 0);
}

如果你觉得难以理解,我会加上解释。

修改

在给定的顺序和预订序列上应用我提到的上述算法,结果树在下面给出 -

enter image description here

答案 1 :(得分:1)

类似的方法,但是为inorder数组使用两个索引如下:

/* keys are between l_p and r_p in the preorder array

   keys are between l_i and r_i in the inorder array
 */
Node * build_tree(int preorder[], long l_p, long r_p,
          int inorder[], long l_i, long r_i)
{
  if (l_p > r_p)
    return nullptr; // arrays sections are empty

  Node * root = new Node(preorder[l_p]); // root is first key in preorder
  if (r_p == l_p)
    return root; // the array section has only a node

  // search in the inorder array the position of the root
  int i = 0;
  for (int j = l_i; j <= r_i; ++j)
    if (inorder[j] == preorder[l_p])
      {
        i = j - l_i;
        break;
      }

  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;
}