根据后序数组重建搜索二叉树
题目
BST 用于测试
class TreeNode():
def __init__(self, val):
self.val = val
self.left = None
self.right = None
class BST():
def __init__(self, root=None):
self.root = root
def insert_recursive(self, val):
def recursive(node, val):
if not node:
return TreeNode(val)
if val < node.val:
node.left = recursive(node.left, val)
elif val > node.val:
node.right = recursive(node.right, val)
return node
self.root = recursive(self.root, val)
def inorder_traversal_recursive(self):
def recursive(node):
if node:
recursive(node.left)
result.append(node.val)
recursive(node.right)
result = []
recursive(self.root)
return result
def preorder_traversal_recursive(self):
def recursive(node):
if node:
result.append(node.val)
recursive(node.left)
recursive(node.right)
result = []
recursive(self.root)
return result
def postorder_traversal_recursive(self):
def recursive(node):
if node:
recursive(node.left)
recursive(node.right)
result.append(node.val)
result = []
recursive(self.root)
return result
给定一个整型数组,其中没有重复值,判断是否可能是二叉树后续遍历结果。
思路
后续遍历序列中,最后一个值为根节点,其余元素分成两半,前部分值都比根小,后部分都比根大。然后递归地判断前部分、后部分是否为后续遍历序列。
实现
def is_post_order(order):
def check(start, end):
if start >= end-1:
return True
index = start
while index < end and order[index] < order[end-1]:
index += 1
i = index
while i < end and order[i] > order[end-1]:
i += 1
if i != end-1:
return False
return check(start, index) and check(index, end-1)
if not order:
return False
return check(0, len(order))
进阶
给定二叉树的后续遍历结果,已知没有重复值,重构二叉树
思路
最后一个元素为根节点,其余元素分成两半,比根小的递归地生成左子树,比根大地后半部分递归地生成右子树。
实现
def build_by_post_order(self, post_order):
def build(start, end):
if start >= end:
return None
v = post_order[end-1]
root = TreeNode(v)
index = start
while index < end and post_order[index] < v:
index += 1
root.left = build(start, index)
root.right = build(index, end-1)
return root
self.root = build(0, len(post_order))
测试
import random
import operator
import unittest
from bst import BST
from bst import is_post_order
class PostOrderToBSTTestCase(unittest.TestCase):
def check_post_order_to_bst_random(self, node_count):
datas = list(range(node_count))
random.shuffle(datas)
bst = BST()
for d in datas:
bst.insert_recursive(d)
post_order = bst.postorder_traversal_recursive()
in_order = bst.inorder_traversal_recursive()
pre_order = bst.preorder_traversal_recursive()
bst2 = BST()
bst2.build_by_post_order(post_order)
post_order2 = bst2.postorder_traversal_recursive()
in_order2 = bst2.inorder_traversal_recursive()
pre_order2 = bst2.preorder_traversal_recursive()
self.assertTrue(operator.eq(pre_order, pre_order2))
self.assertTrue(operator.eq(in_order, in_order2))
self.assertTrue(operator.eq(post_order, post_order2))
def test_post_order_to_bst_10(self):
for _ in range(100):
self.check_post_order_to_bst_random(10)
def test_post_order_to_bst_100(self):
for _ in range(100):
self.check_post_order_to_bst_random(100)
def test_post_order_to_bst_1000(self):
for _ in range(100):
self.check_post_order_to_bst_random(1000)
def test_is_post_order_10(self):
for _ in range(100):
bst = BST()
datas = list(range(10))
random.shuffle(datas)
for d in datas:
bst.insert_recursive(d)
post_order = bst.postorder_traversal_recursive()
self.assertTrue(is_post_order(post_order))
def test_not_post_order_10(self):
for _ in range(100):
bst = BST()
datas = list(range(10))
random.shuffle(datas)
for d in datas:
bst.insert_recursive(d)
node = bst.root
while not node.left or not node.right:
if not node.left:
node = node.right
if not node.right:
node = node.left
if not node.left or not node.right:
continue
node.left, node.right = node.right, node.left
post_order = bst.postorder_traversal_recursive()
self.assertFalse(is_post_order(post_order))
结果
~/code/data_structure_and_algorithms/coding_interview_guide/3_binary_tree/14_post_order_to_bst(master ✔) python3.8 -m unittest test_post_order_to_bst.py
.....
----------------------------------------------------------------------
Ran 5 tests in 0.588s
OK