如何使用{先序、中序、后序}遍历结果重建二叉搜索树

3
我们知道先序遍历、中序遍历和后序遍历。有哪些算法可以重构二叉搜索树?
4个回答

12

由于这是BST,所以可以从先序遍历后序遍历中的中序遍历进行排序<1>。实际上,只需要其中一种遍历方式即可....

<1>如果您知道比较函数是什么


先序遍历中序遍历构建二叉树

BT createBT(int* preOrder, int* inOrder, int len)
{
    int i;
    BT tree;
    if(len <= 0)
        return NULL;
    tree = new BTNode;
    t->data = *preOrder;
    for(i = 0; i < len; i++)
        if(*(inOrder + i) == *preOrder)
            break;
    tree->left = createBT(preOrder + 1, inOrder, i);
    tree->right = createBT(preOrder + i + 1, inOrder + i + 1, len - i - 1);
    return tree;
}

这样做的原理是:

在先序遍历中,第一个节点是根节点。在中序遍历中找到根节点,然后将树分为左子树和右子树。递归执行此操作。

后序遍历中序遍历同理。


关于第一句话:这是假设您知道比较函数是什么... - Aryabhatta
江,你能否解释一下为什么对于右子节点,前序遍历从 preOrder + i + 1 开始? - brainydexter

0

这里是一个 Ruby 递归解决方案

def rebuild(preorder, inorder)
  root = preorder.first
  root_inorder = inorder.index root
  return root unless root_inorder
  root.left = rebuild(preorder[1, root_inorder], inorder[0...root_inorder])
  root.right = rebuild(preorder[root_inorder+1..-1], inorder[root_inorder+1..-1])
  root
end

还有一个例子

class Node
  attr_reader :val
  attr_accessor :left, :right

  def initialize(val)
    @val = val
  end

  def ==(node)
    node.val == val
  end

  def inspect
    "val: #{val}, left: #{left && left.val || "-"}, right: #{right && right.val || "-"}"
  end
end

inorder = [4, 7, 2, 5, 1, 3, 8, 6, 9].map{|v| Node.new v }
preorder = [1, 2, 4, 7, 5, 3, 6, 8, 9].map{|v| Node.new v }

tree = rebuild(preorder, inorder)
tree
# val: 1, left: 2, right: 3
tree.left
# val: 2, left: 4, right: 5
tree.left.left
# val: 4, left: -, right: 7

0
重建二叉树需要先序遍历和中序遍历或后序遍历和中序遍历。对于BST,我们可以使用先序遍历或后序遍历来重建,因为对它们进行排序将给出中序遍历。
您可以使用以下函数,这是对@brainydexter提供的代码进行修改以在不使用静态变量的情况下重建树的函数:
struct node* buildTree(char in[],char pre[], int inStrt, int inEnd,int preIndex){

    // start index > end index..base condition return NULL.
    if(inStrt > inEnd)
        return NULL;

    // build the current node with the data at pre[preIndex].
    struct node *tNode = newNode(pre[preIndex]);

    // if all nodes are constructed return. 
    if(inStrt == inEnd)
        return tNode;

    // Else find the index of this node in Inorder traversal
    int inIndex = search(in, inStrt, inEnd, tNode->data);

    // Using index in Inorder traversal, construct left and right subtress
    tNode->left = buildTree(in, pre, inStrt, inIndex-1,preIndex+1);
    tNode->right = buildTree(in, pre, inIndex+1, inEnd,preIndex+inIndex+1);

    return tNode;
}

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接