Algorithm 从顺序和后序遍历构造二叉树

Algorithm 从顺序和后序遍历构造二叉树,algorithm,recursion,tree,depth-first-search,Algorithm,Recursion,Tree,Depth First Search,我正在尝试从后序和顺序遍历构造一个二叉树。我相信递归部分是正确的,但是我不确定基本情况。任何指点都将不胜感激 我尝试了不同的基本案例组合,但似乎无法使其发挥作用 类二进制树节点: 定义初始化(self,data=None,left=None,right=None): self.data=数据 self.left=左 self.right=right def二叉树\u from\u posterorder\u inoorder(posterorder,inoorder): node_to_inoo

我正在尝试从后序和顺序遍历构造一个二叉树。我相信递归部分是正确的,但是我不确定基本情况。任何指点都将不胜感激

我尝试了不同的基本案例组合,但似乎无法使其发挥作用

类二进制树节点:
定义初始化(self,data=None,left=None,right=None):
self.data=数据
self.left=左
self.right=right
def二叉树\u from\u posterorder\u inoorder(posterorder,inoorder):
node_to_inoorder_idx={data:i代表i,枚举中的数据(inoorder)}
def助手(
顺序开始,顺序结束,顺序开始,顺序结束
):

如果postorder\u end>=postorder\u start或inorder\u end我已经有一段时间没有处理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}
: {
瓦尔,
…(idx>0?{左:makeTree(postord.slice(0,idx),inord.slice(0,idx))}:{},
…(idx)
我已经有一段时间没有处理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}
: {
瓦尔,
…(idx>0?{左:makeTree(postord.slice(0,idx),inord.slice(0,idx))}:{},
…(idx)
再摆弄一会儿,我就可以解决这个问题了。请参见下面我更新的功能:

def binary_tree_from_posterorder_inoorder(posterorder,inoorder):
如果不按顺序或不按顺序或按顺序排列(按顺序排列)!=len(顺序):
一无所获
node_to_inoorder_idx={data:i代表i,枚举中的数据(inoorder)}
def帮助程序(postorder\u开始、postorder\u结束、inorder\u开始、inorder\u结束):
如果postorder\u start>postorder\u end或inorder\u start>inorder\u end:
一无所获
root\u index=节点\u到\u顺序\u idx[后序[后序\u结束]]
左子树大小=根索引-顺序开始
返回二叉树烯(
邮购[邮购结束],
助手(
订单启动后,
后序开始+左子树大小-1,
为了开始,
根_指数-1,
),
助手(
后序开始+左子树大小,
邮购结束-1,
根索引+1,
最后,,
),
)
返回帮助程序(0,len(postorder)-1,0,len(inorder)-1)

再摆弄一会儿,我就可以解决这个问题了。请参见下面我更新的功能:

def binary_tree_from_posterorder_inoorder(posterorder,inoorder):
如果不按顺序或不按顺序或按顺序排列(按顺序排列)!=len(顺序):
一无所获
node_to_inoorder_idx={data:i代表i,枚举中的数据(inoorder)}
def帮助程序(postorder\u开始、postorder\u结束、inorder\u开始、inorder\u结束):
如果postorder\u start>postorder\u end或inorder\u start>inorder\u end:
一无所获
root\u index=节点\u到\u顺序\u idx[后序[后序\u结束]]
左子树大小=根索引-顺序开始
返回二叉树烯(
邮购[邮购结束],
助手(
订单启动后,
后序开始+左子树大小-1,
为了开始,
根_指数-1,
),
助手(
后序开始+左子树大小,
邮购结束-1,
根索引+1,
最后,,
),
)
返回帮助程序(0,len(postorder)-1,0,len(inorder)-1)

请添加语言标签并发布@c0,因为我刚刚编辑了我的问题并添加了完整的程序。谢谢大家!
root\u left=helper….
调用不完整。请修复。预期的输出格式是什么?我以为你想要一棵树,很抱歉又错过了。我没有把它复制好。我现在修复了。请添加语言标签并发布@c0der。我刚刚编辑了我的问题并添加了我的完整程序。谢谢大家!
root\u left=helper….
调用不完整。请修复。预期的输出格式是什么?我以为你想要一棵树,很抱歉又错过了。我没有把它复制好。我现在修好了。谢谢你花时间写下你的详细回复。在对它进行了一点修改之后,我能够实现它,我所做的更改是使用postorder_end索引来确定根,而不是对postorder_start和postorder_end使用反向索引,并通过一个end索引删除。我还可以使用
reduce
来实现同样的效果。我也喜欢你把这一切可视化的方式。@Mahdi:这被认为是绝对可行的