ค้นหา Complete Subtree ที่มีขนาดใหญ่ที่สุด
Complete Binary Tree คือต้นไม้ไบนารีที่ทุกระดับเต็มไปด้วยโหนด ยกเว้นระดับสุดท้ายที่อาจไม่เต็ม และโหนดในระดับสุดท้ายต้องชิดซ้ายมากที่สุด
โจทย์: หาขนาด (จำนวนโหนด) ของ Complete Subtree ที่ใหญ่ที่สุดใน Binary Tree ที่กำหนด
แนวคิดการแก้ปัญหา
ใช้การท่องต้นไม้แบบ Post-order พร้อมเก็บข้อมูลของแต่ละโหนด:
isPerfect: เป็น Perfect Binary Tree หรือไม่ (ทุกระดับเต็ม)isComplete: เป็น Complete Binary Tree หรือไม่size: จำนวนโหนดใน Subtree ที่รากที่โหนดนี้rootTree: รากของ Complete Subtree ใหญ่ที่สุดใน Subtree นี้
เงื่อนไขสำคัญ:
- ถ้าต้นซ้ายเป็น Perfect และต้นขวาเป็น Complete และความสูงเท่ากัน → โหนดปัจจุบันเป็น Complete (และ Perfect ถ้าต้นขวา Perfect)
- ถ้าต้นซ้ายเป็น Complete และต้นขวาเป็น Perfect และความสูงซ้าย = ความสูงขวา + 1 → โหนดปัจจุบันเป็น Complete (แต่ไม่ Perfect)
- มิฉะนั้น โหนดปัจจุบันไม่ใช่ Complete → เลือก Complete Subtree ใหญ่สุดจากลูกซ้ายหรือขวา
โค้ดตัวอย่าง Python
import math
class TreeNode:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
class ReturnType:
def __init__(self):
self.isPerfect = False
self.isComplete = False
self.size = 0
self.rootTree = None
def getHeight(size):
return int(math.ceil(math.log(size + 1, 2)))
def checkCompleteness(root):
ret = ReturnType()
if root is None:
ret.isPerfect = True
ret.isComplete = True
ret.size = 0
ret.rootTree = None
return ret
left = checkCompleteness(root.left)
right = checkCompleteness(root.right)
# Case 1: Left Perfect, Right Complete, same height
if left.isPerfect and right.isComplete and getHeight(left.size) == getHeight(right.size):
ret.isComplete = True
ret.isPerfect = right.isPerfect
ret.size = left.size + right.size + 1
ret.rootTree = root
return ret
# Case 2: Left Complete, Right Perfect, left height = right height + 1
if left.isComplete and right.isPerfect and getHeight(left.size) == getHeight(right.size) + 1:
ret.isComplete = True
ret.isPerfect = False
ret.size = left.size + right.size + 1
ret.rootTree = root
return ret
# Not complete at this node
ret.isPerfect = False
ret.isComplete = False
ret.size = max(left.size, right.size)
ret.rootTree = left.rootTree if left.size > right.size else right.rootTree
return ret
def print_inorder(root):
if root:
print_inorder(root.left)
print(root.data, end=', ')
print_inorder(root.right)
# ตัวอย่าง
root = TreeNode(50)
root.left = TreeNode(30)
root.right = TreeNode(60)
root.left.left = TreeNode(5)
root.left.right = TreeNode(20)
root.right.left = TreeNode(45)
root.right.right = TreeNode(70)
root.right.left.left = TreeNode(10)
ans = checkCompleteness(root)
print("Size:", ans.size)
print("Inorder Traversal:", end=' ')
print_inorder(ans.rootTree)
# Output: Size: 4, Inorder: 10, 45, 60, 70,