"""
二叉树数组表示:根据层序遍历的特性,我们可以推导出父节点索引与子节点索引之间的“映射公式”:
若某节点的索引为 i,则该节点的左子节点索引为 2i + 1,右子节点索引为 2i + 2。

完美二叉树是一个特例,在二叉树的中间层通常存在许多 None.
了解决此问题,我们可以考虑在层序遍历序列中显式地写出所有 None。样处理后,层序遍历序列就可以唯一表示二叉树了。
"""


class ArrayBinaryTree:
    def __init__(self, arr: list[int | None]):
        self._tree = list(arr)

    def size(self):
        return len(self._tree)

    def val(self, i: int) -> int | None:
        """获取索引为i的节点的值"""
        if i < 0 or i >= self.size():
            return None
        return self._tree[i]

    def left(self, i: int) -> int | None:
        """获取索引为 i 节点的左子节点的索引"""
        return 2 * i + 1

    def right(self, i: int) -> int:
        return 2 * i + 2

    def parent(self, i: int) -> int:
        return (i - 1) // 2

    def level_order(self) -> int:
        for i in self._tree:
            if i:
                yield i

    def dfs(self, i: int, order: str):
        """深度优先遍历"""
        if self.val(i) is None:
            return
        # 前序遍历
        if order == "pre":
            self.res.append(self.val(i))
        self.dfs(self.left(i), order)
        # 中序遍历
        if order == "in":
            self.res.append(self.val(i))
        self.dfs(self.right(i), order)
        # 后序遍历
        if order == "post":
            self.res.append(self.val(i))