LoginSignup
0
2

More than 3 years have passed since last update.

木の巡回配列から二分木を生成する

Last updated at Posted at 2019-09-27

概要

二分木の深さ優先探索(DFS)には先行順巡回:pre-order, 中間順巡回:in-order, 後行順巡回:post-orderの3通りの方法がありますが、そのうち中間順巡回と先行(後行)順巡回の2つの配列が与えられれば、対象となる二分木を生成することができます。本記事ではin-orderとpost-orderの配列から二分木を生成する方法を紹介します。

方針

まず、pre-orderの場合は先頭の要素、post-orderの場合は最後尾の要素がrootになることに着目します。また、in-orderの配列をrootの要素の位置で分割した場合、左側の部分配列はrootの左の部分木、右側の部分配列はrootの右の部分木のそれぞれのin-orderになります。そこで下記の手順を再帰的に繰り返すことで、二分木を生成することができます。

  1. post-orderの配列の最後尾をrootの値として取り出す
  2. in-orderの配列を、rootの値の位置を中心に分割する
  3. 左右に分割したin-orderの配列と、最後尾を除いたpost-orderの配列からsub-treeを生成し、それぞれrootの子ノードにセットする

実装例

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution(object):
    def buildTree(self, inorder, postorder):
        # post-orderの最後尾をrootの値として取り出す
        rootVal = postorder.pop()

        # in-orderの配列を分割するため、rootValのindexを取得する
        rootIdx = inorder.index(rootVal)

        root = TreeNode(rootVal)

        # in-orderの配列をrootIdxを中心に分割し、左右の部分木を再帰的に生成する
        if len(postorder) > 0 and rootIdx < len(inorder) - 1:
            root.right = self.buildTree(inorder[rootIdx+1:], postorder)
        if len(postorder) > 0 and rootIdx > 0:
            root.left = self.buildTree(inorder[:rootIdx], postorder)

        return root

実行

# 下記のような二分木を生成する
#    3
#   / \
#  9  20
#    /  \
#   15   7

inorder = [9,3,15,20,7]
postorder = [9,15,7,20,3]

root = Solution().buildTree(inorder, postorder)
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2