我试图从后序遍历和有序遍历构造一个二叉树。我相信递归部分是正确的,但我不确定基本情况任何指点都将不胜感激。
我尝试过不同的基本案例组合,但似乎无法奏效。

class BinaryTreeNode:
    def __init__(self, data=None, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right


def binary_tree_from_postorder_inorder(postorder, inorder):
    node_to_inorder_idx = {data: i for i, data in enumerate(inorder)}


    def helper(
        postorder_start, postorder_end, inorder_start, inorder_end
    ):
        if postorder_end >= postorder_start or inorder_end <= inorder_start:
            return None


        root_inorder_idx = node_to_inorder_idx[postorder[postorder_start]]
        left_subtree_size = root_inorder_idx - inorder_start

        root = BinaryTreeNode(postorder[postorder_start])

        root.right = helper(
            postorder_start - 1,
            postorder_start - 1 - left_subtree_size,
            root_inorder_idx + 1,
            inorder_end,
        )
        root.left = helper(
            postorder_start - 1 - left_subtree_size,
            postorder_end,
            inorder_start,
            root_inorder_idx,
        )

        return root

     return helper(len(postorder) - 1, -1, 0, len(inorder))

def inorder(tree):
    stack = []
    results = []

    while stack or tree:
        if tree:
            stack.append(tree)
            tree = tree.left
        else:
            tree = stack.pop()
            results.append(tree.data)
            tree = tree.right
    return results


inorder = ["F", "B", "A", "E", "H", "C", "D", "I", "G"]
postorder = ["F", "A", "E", "B", "I", "G", "D", "C", "H"]

root_pos_in = binary_tree_from_postorder_inorder(postorder, inorder)

print(inorder(root_pos_in))

输入:
inorder = ["F", "B", "A", "E", "H", "C", "D", "I", "G"]
postorder = ["F", "A", "E", "B", "I", "G", "D", "C", "H"]

使用顺序遍历的实际输出:
["A", "B", "E", "H", "C"]
预期产量:
["F", "B", "A", "E", "H", "C", "D", "I", "G"]

最佳答案

我处理python已经有一段时间了,但是看起来这是一个简单算法的大量代码。
下面是算法应用的一个例子:
我们从

postorder  |  inorder
-----------|----------
           |
FAEBIGDCH  | FBAEHCDIG
        ^  |
        |  |
         `-+-------------- last value of postorder: 'H': this is the root value
           |
FAEBIGDCH  | FBAEHCDIG
           |     ^
           |     |
           |      `------- index of 'H' in inorder: 4
           |
FAEB_....  | FBAE_....
  ^        |   ^
  |        |   |
  |        |    `--------- everything before index 4
  |        |
   `-------+-------------- everything before index 4
           |
....IGDC_  | ...._CDIG
      ^    |        ^
      |    |        |
      |    |         `---- everything beginning with index 5 (4 + 1)
      |    |
       `---+-------------- everything between index 4 and the 'H' at the end
           |
FAEB       | FBAE
  ^        |   ^
  |        |   |
   `-------+---+---------- recur on these if not empty: this is the left child
           |
     IGDC  |      CDIG
       ^   |        ^
       |   |        |
        `--+--------+----- recur on these if not empty: this is the right child

这会很快把我们引向一棵树
               H
               |
      +--------+--------+
      |                 |
      B                 C
      |                 |
+-----+-----+           +-----+
|           |                 |
F           E                 D
            |                 |
        +---+                 +---+
        |                         |
        A                         G
                                +-+
                                |
                                I

因此,虽然我不能真正批评您的Python,但我可以提供一个非常简单的JS版本:
const makeTree = (
    postord, inord,
    len = postord.length, val = postord[len - 1], idx = inord.indexOf(val)
  ) =>
    len == 1
      ? {val}
    : {
        val,
        ...(idx > 0 ? {left: makeTree(postord.slice(0, idx), inord.slice(0, idx))} : {}),
        ...(idx < len - 1 ? {right: makeTree(postord.slice(idx, len - 1), inord.slice(idx + 1, len))} : {})
      }

const postOrder = ["F", "A", "E", "B", "I", "G", "D", "C", "H"]
const inOrder =   ["F", "B", "A", "E", "H", "C", "D", "I", "G"]

console .log (
  makeTree (postOrder, inOrder)
)

07-28 12:02