Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬(Python)으로 각 노드에 왼쪽·오른쪽 서브트리 합을 더해 트리를 변환하는 프로그램


이진 트리(binary tree)가 하나 주어져 있다고 가정해 보겠습니다. 이때 구해야 할 것은 기존 트리와 구조는 같지만, 모든 노드의 값을 '자기 자신의 값 + 왼쪽 서브트리의 합 + 오른쪽 서브트리의 합'으로 대체한 새로운 트리입니다.

예를 들어 입력 트리가 다음과 같다면,

파이썬(Python)으로 각 노드에 왼쪽·오른쪽 서브트리 합을 더해 트리를 변환하는 프로그램


출력 결과는 아래와 같습니다.

파이썬(Python)으로 각 노드에 왼쪽·오른쪽 서브트리 합을 더해 트리를 변환하는 프로그램

문제 해결 접근 방법

이 문제는 재귀적인 후위 순회(post-order traversal)를 활용하면 간단하게 해결할 수 있습니다. 자식 노드들의 합계를 먼저 계산한 뒤 부모 노드의 값을 갱신하는 방식입니다. 알고리즘의 동작 순서는 다음과 같습니다.

  • tree_sum() 함수를 정의합니다. 이 함수는 트리의 루트 노드를 인자로 받습니다.

  • 루트가 null(None)이라면 0을 반환합니다.

  • 루트의 데이터 값을 다음과 같이 갱신합니다.
    root.data = tree_sum(root.left) + tree_sum(root.right) + root.data

  • 갱신된 루트의 데이터를 반환합니다.

  • 메인 메서드에서는 tree_sum(root)를 호출한 뒤 root를 반환합니다.

구현 예제

아래 코드를 통해 더 잘 이해해 보겠습니다.

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

def inorder(root):
   if root:
       inorder(root.left)
       print(root.data, end=', ')
       inorder(root.right)

class Solution:
   def solve(self, root):
       def tree_sum(root: TreeNode):
           if root is None:
               return 0
           root.data = tree_sum(root.left) + tree_sum(root.right) + root.data
           return root.data
       tree_sum(root)
       return root

ob = Solution()
root = TreeNode(2)
root.left = TreeNode(3)
root.right = TreeNode(4)
root.left.left = TreeNode(9)
root.left.right = TreeNode(7)
ob.solve(root)
inorder(root)

입력

root = TreeNode(2)
root.left = TreeNode(3)
root.right = TreeNode(4)
root.left.left = TreeNode(9)
root.left.right = TreeNode(7)

출력

9, 19, 7, 25, 4,

결과 설명

중위 순회(inorder) 순서로 살펴보면 각 노드의 값이 다음과 같이 변경됩니다.

  • 값이 9였던 노드 → 리프 노드이므로 그대로 9

  • 값이 3이었던 노드 → 3 + 9(왼쪽) + 7(오른쪽) = 19

  • 값이 7이었던 노드 → 리프 노드이므로 그대로 7

  • 값이 2였던 루트 노드 → 2 + 19(왼쪽 서브트리 전체 합) + 4(오른쪽) = 25

  • 값이 4였던 노드 → 리프 노드이므로 그대로 4

이처럼 재귀 호출이 가장 깊은 곳(리프 노드)부터 값을 계산해 올라오면서 부모 노드에 누적되는 구조이기 때문에, 한 번의 트리 순회만으로 모든 노드를 O(n) 시간 복잡도 안에 갱신할 수 있습니다.