Leetcode 바이너리 트리의 순차 순회-Python은 세 가지 솔루션을 구현합니다.

0 주제 설명

Leetcode 원래 제목에 대한 링크 : 이진 트리의 순차 순회
여기에 사진 설명 삽입

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

1 재귀 알고리즘

아이디어와 알고리즘
우선, 우리는 이진 트리의 순차 순회가 무엇인지 이해해야합니다. 왼쪽 하위 트리 루트 노드 오른쪽 하위 트리를 방문하는 방식으로이 트리를 순회하고 왼쪽 하위 트리 또는 오른쪽 하위 트리를 방문 할 때 전체 트리가 순회 될 때까지 같은 방식으로 순회합니다. 따라서 전체 순회 프로세스는 자연스럽게 재귀 적이며 재귀 함수를 사용하여이 프로세스를 직접 시뮬레이션 할 수 있습니다.
inorder (root) 정의는 현재 루트 노드로 이동하는 응답을 나타내며, 정의에 따라 루트 노드의 왼쪽 하위 트리를 탐색하기 위해 inorder (root.left)를 재귀 적으로 호출 한 다음 응답에 루트 노드의 값을 추가 한 다음 재귀 적으로 inorder를 호출하면됩니다. (root.right) 루트 노드의 오른쪽 하위 트리를 순회하려면 순환 종료 조건은 빈 노드를 만나는 것입니다.

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)

알고리즘 복잡도
시간 복잡도 : O (n) O (n)O ( n ) , 여기서nnn 은 이진 트리 노드의 수입니다. 이진 트리 순회에서 각 노드는 한 번만 방문합니다.
공간 복잡성 :O (n) O (n)O ( n ) . 공간 복잡도는 재귀 스택 깊이에 따라 다르며 스택 깊이는 이진 트리가 체인 일 때O (n) O (n)에도달 할 수 있습니다.O ( n ) 수준.

2 반복 알고리즘 (스택)

반복적 인 방식으로 재귀 함수를 구현할 수도 있습니다. 두 가지 방법은 동일합니다. 차이점은 스택이 재귀 중에 암시 적으로 유지되고 반복 할 때이 스택을 명시 적으로 시뮬레이션해야한다는 것입니다.

# 其核心思想如下:
# 使用颜色标记节点的状态,新节点为白色,已访问的节点为灰色。
# 如果遇到的节点为白色,则将其标记为灰色,然后将其右子节点、自身、左子节点依次入栈。
# 如果遇到的节点为灰色,则将节点的值输出。
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        White, Gray = 0, 1
        res = []
        stack = [(White,root)]
        while stack:
            color, node = stack.pop()
            if not node: continue
            if color == White:
                stack.append((White,node.right))
                stack.append((Gray,node))
                stack.append((White,node.left))
            else:
                res.append(node.val)
        return res

알고리즘 복잡도
시간 복잡도 : O (n) O (n)O ( n ) , 여기서nnn 은 이진 트리 노드의 수입니다. 이진 트리 순회에서 각 노드는 한 번만 방문합니다.
공간 복잡성 :O (n) O (n)O ( n ) . 공간 복잡도는 재귀 스택 깊이에 따라 다르며 스택 깊이는 이진 트리가 체인 일 때O (n) O (n)에도달 할 수 있습니다.O ( n ) 수준.

3 Morris 순회 순회

아이디어 및 알고리즘
Morris 순회 알고리즘은 O (1)에 대한 비 재귀 순회 순회의 공간 복잡성을 줄일 수있는 이진 트리를 순회하는 또 다른 방법입니다.
Morris traversal은 일정한 공간 순회 방법이며, 그 본질은 스레드 된 이진 트리 (Threaded Binary Tree)이며, 실제로는 이진 트리에서 NULL에 대한 n + 1 포인터를 사용합니다.
순회 프로세스 동안 Morris 순회는 리프 노드의 빈 오른쪽 포인터를 사용하여 순회 순회의 후속 노드를 가리 키므로 스택에 대한 종속성을 피합니다.여기에 사진 설명 삽입
여기에 사진 설명 삽입

# (1)对于一个节点cur,找到它左子树的最右节点,看这个节点的right指针是null还是指向cur。
# (2)如果是null,说明左子树还没处理过,更新该指针为cur,然后进入左子树继续上述流程。
# (3)如果该指针已经是cur了,说明左子树已经处理完毕,现在是处理完毕后顺这最右节点的right指针回到该cur节点的,需先将该right指针恢复为null,处理该cur节点后进入右子树重复流程⑴。
class Solution:
    def inorderTraversal(self, root: TreeNode) -> list:
        node, res = root, []
        while node:
            if not node.left:
                res.append(node.val)
                node = node.right
            else:
                pre = node.left
                while pre.right and pre.right != node:
                    pre = pre.right
                if not pre.right:
                    pre.right = node
                    node = node.left
                else:
                    pre.right = None
                    res.append(node.val)
                    node = node.right
        return res

알고리즘 복잡도
시간 복잡도 : O (n) O (n)O ( n ) , 여기서nnn 은 이진 검색 트리의 노드 수입니다. Morris traversal에서 각 노드는 두 번 방문하므로 총 시간 복잡도는O (2n) O (2n)입니다.O ( 2 N ) =O (n)은 O (N)O ( n ) .
공간 복잡성 :O (1) O (1)O ( 1 )

참고

색상 표기법-트리 순회에 대한 일반적이고 간결한 방법
Morris 순회

추천

출처blog.csdn.net/OuDiShenmiss/article/details/109197755