def dfs(i): # Check if subtree is empty. if s[i] in ['(', ')']: return None, i start = i # while i < n and (s[i] == '-' or s[i].isdigit()): while i < n and s[i] not in ['(', ')']: i += 1 # if start == i: # alternative to checking s[i] at start # return None, i node = TreeNode(int(s[start:i])) if i < n and s[i] == '(': # left subtree i += 1 # skip '(' node.left, i = dfs(i) i += 1 # skip ')' if i < n and s[i] == '(': # right subtree i += 1 # skip '(' node.right, i = dfs(i) i += 1 # skip ')' return node, i
def test_tree_case3(self): # 1 # 2 # 3 node3 = TreeNode(3) node2 = TreeNode(2, right=node3) node1 = TreeNode(1, right=node2) tree1 = BinaryTree(node1) assert tree1.root is node1 assert tree1.is_empty() is False assert tree1.size == 3 assert tree1.levels == 3 assert tree1.serialize() == '1,#,2,#,#,#,3' assert tree1.level_order() == [[1], [2], [3]] assert tree1.pre_order() == [1, 2, 3] assert tree1.in_order() == [1, 2, 3] assert tree1.post_order() == [3, 2, 1] tree2 = BinaryTree(serialize=tree1.serialize()) assert tree2.root.val == 1 assert tree2.is_empty() is False assert tree2.size == 3 assert tree2.levels == 3 assert tree2.serialize() == '1,#,2,#,#,#,3' assert tree2.level_order() == [[1], [2], [3]] assert tree2.pre_order() == [1, 2, 3] assert tree2.in_order() == [1, 2, 3] assert tree2.post_order() == [3, 2, 1] assert tree1 == tree2
def invertTree(self, root: TreeNode) -> TreeNode: if not root: return None right, left = root.right, root.left root.left = self.invertTree(right) root.right = self.invertTree(left) return root
def str2tree(self, s: str) -> TreeNode: if not s: return None # Find first '(' i = s.find('(') if i < 0: return TreeNode(int(s)) # Find index j of char ')' that ends left subtree net = 0 j = i while j < len(s): if s[j] == '(': net += 1 elif s[j] == ')': net -= 1 if net == 0: break j += 1 root = TreeNode(int(s[:i])) root.left = self.str2tree(s[i + 1:j]) # exclude parentheses at this level root.right = self.str2tree( s[j + 2:-1]) # exclude parentheses at this level return root
def giant_tree(): """Fixture to generate a massive binary tree.""" import random def get_random_node_value(size): """Function to get a random node value""" nonlocal node_ids node_value = 0 while node_value in node_ids: node_value = random.randint(0, size) node_ids.update({node_value}) return node_value node = TreeNode(1) node_ids = {1} node_ = node size = 10000 # re-enable this if checking with larger binary trees. # sys.setrecursionlimit(size) while len(node_ids) < size: node_.left_child = TreeNode(get_random_node_value(size)) node_.right_child = TreeNode(get_random_node_value(size)) if random.random() < 0.5: node_ = node_.left_child else: node_ = node_.right_child yield node del node
def test_is_balanced(): tree1 = TreeNode.from_list([ [0], [1, None], [2, None, None, None]]) assert not is_balanced(tree1) tree2 = TreeNode.from_list([ [0], [1, 1], [2, None, None, None]]) assert is_balanced(tree2) tree3 = TreeNode.from_list([ [0], [1, 1], [2, None, None, None], [3, None, None, None, None, None, None, None]]) assert not is_balanced(tree3) tree4 = TreeNode.from_list([ [0], [1, 1], [2, 2, 2, None], [3, None, None, None, None, None, None, None]]) assert is_balanced(tree4)
def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode: if not t1 or not t2: return t1 or t2 q1 = collections.deque([t1]) q2 = collections.deque([t2]) while q1 and q2: node1 = q1.popleft() node2 = q2.popleft() if node1 and node2: node1.val = node1.val + node2.val if (not node1.left) and node2.left: node1.left = TreeNode(0) if (not node1.right) and node2.right: node1.right = TreeNode(0) q1.append(node1.left) q1.append(node1.right) q2.append(node2.left) q2.append(node2.right) return t1
def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode: if not t1: return t2 root = t1 stack = [(t1, t2)] while stack: t1, t2 = stack.pop() if not t1 or not t2: continue t1.val += t2.val if not t1.left: t1.left = t2.left elif t2.left: # both t1 and t2 have left nodes stack.append((t1.left, t2.left)) if not t1.right: t1.right = t2.right elif t2.right: # both t1 and t2 have right nodes stack.append((t1.right, t2.right)) return root
def dfs(start, end): if start >= end: return None # Find first '(' i = s.find('(', start, end) if i < 0: return TreeNode(int(s[start:end])) # Find index j of char ')' that ends left subtree net = 0 for j in range(i, end): if s[j] in d: net += d[s[j]] if net == 0: break root = TreeNode(int(s[start:i])) root.left = dfs(i + 1, j) # exclude parentheses at this level root.right = dfs(j + 2, end - 1) # exclude parentheses at this level return root
def setUp(self): self.data = [ ( TreeNode( val=3, left=TreeNode( val=9, left=None, right=None, ), right=TreeNode( val=20, left=TreeNode( val=15, left=None, right=None, ), right=TreeNode( val=7, left=None, right=None, ), ), ), [ [3], [9, 20], [15, 7], ], ), ]
def test_tree_case4(self): # 1 # 2 3 # 4 5 node4 = TreeNode(4) node2 = TreeNode(2, left=node4) node5 = TreeNode(5) node3 = TreeNode(3, right=node5) node1 = TreeNode(1, node2, node3) tree1 = BinaryTree(node1) assert tree1.root is node1 assert tree1.is_empty() is False assert tree1.size == 5 assert tree1.levels == 3 assert tree1.serialize() == '1,2,3,4,#,#,5' assert tree1.level_order() == [[1], [2, 3], [4, 5]] assert tree1.pre_order() == [1, 2, 4, 3, 5] assert tree1.in_order() == [4, 2, 1, 3, 5] assert tree1.post_order() == [4, 2, 5, 3, 1] tree2 = BinaryTree(serialize=tree1.serialize()) assert tree2.root.val == 1 assert tree2.is_empty() is False assert tree2.size == 5 assert tree2.levels == 3 assert tree2.serialize() == '1,2,3,4,#,#,5' assert tree2.level_order() == [[1], [2, 3], [4, 5]] assert tree2.pre_order() == [1, 2, 4, 3, 5] assert tree2.in_order() == [4, 2, 1, 3, 5] assert tree2.post_order() == [4, 2, 5, 3, 1] assert tree1 == tree2
def create_tree_data(self, tokens): output = self.cnn_instance.sentence_score(tokens) sentence = " ".join(tokens) sentence = sentence.strip(" ") sentenceid = self.cnn_instance.p2s[self.cnn_instance.id_dict[sentence]] # tree contains a list of string(numbers) in Stree.txt for a specific sentence tree = self.cnn_instance.parseTrees[sentenceid] treesize = len(tree) nodemap = {} orders_min = {} orders_max = {} root = None od = 0 size = len(tokens) for j in xrange(len(tokens)): # id starts from 1 currNode = TreeNode(None, tokens[j], j+1, True) nodemap[j+1] = currNode orders_min[j+1] = j + 1 orders_max[j+1] = j + 1 for i, item in enumerate(tree): childid = i + 1 parentid = int(item) if parentid not in nodemap: parentnode = TreeNode(None, None, parentid) orders_min[parentid] = float("inf") orders_max[parentid] = float("-inf") nodemap[parentid] = parentnode else: parentnode = nodemap[parentid] nodemap[childid].insert_parent(parentnode) orders_min[parentid] = min(orders_min[parentid], min(orders_min[ch.id] for ch in parentnode.children)) orders_max[parentid] = min(orders_min[parentid], max(orders_min[ch.id] for ch in parentnode.children)) if len(parentnode.children) == 2: if orders_max[parentnode.children[0].id] > orders_max[parentnode.children[1].id]: parentnode.children.reverse() parentval = [] for ch in parentnode.children: parentval.extend(ch.val) parentnode.val = parentval # root is the child of root 0. root = nodemap[i+1] inputs = self.level_order_traverse(root, orders_min, orders_max) #print inputs return inputs, output, root
def build_mirror(root): if not root: return None t = TreeNode(root.val) t.left = build_mirror(root.right) t.right = build_mirror(root.left) return t
def test_init(): node_left = TreeNode(1) node_right = TreeNode(2) root = TreeNode(0, left=node_left, right=node_right) tree = BinaryTree(root) assert tree.root == root assert tree.root.left == node_left assert tree.root.right == node_right
def construct(qianxu, zhongxu): if not qianxu or not zhongxu: return root = TreeNode(qianxu[0]) pos = zhongxu.index(qianxu[0]) root.left = construct(qianxu[1:pos + 1], zhongxu[0:pos]) root.right = construct(qianxu[pos + 1:], zhongxu[pos + 1:]) return root
def test_mount(): root = TreeNode(5, VALUE) sub_node = TreeNode(3, VALUE) root.mount_left(sub_node) assert sub_node == root._left assert sub_node._parent == root assert root._right_height == 0 assert root._left_height == 1
def dfs_bottom_up(p: TreeNode, parent: TreeNode) -> TreeNode: if p is None: return parent root = dfs_bottom_up(p.left, p) if parent is None: p.left = None else: p.left = parent.right p.right = parent return root
def test_false(self): t = TreeNode(1) t.left = TreeNode(2) t.right = TreeNode(2) t.left.left = TreeNode(3) t.left.right = TreeNode(3) t.left.left.left = TreeNode(4) t.left.left.right = TreeNode(4) self.assertFalse(BruteForceTopDownRecursion().isBalanced(t)) self.assertFalse(BottomUp().isBalanced(t))
def _sortedArrayToBST(self, nums, low, high): if low > high: return None if low == high: return TreeNode(nums[low]) mid = low + (high - low) // 2 root = TreeNode(nums[mid]) root.left = self._sortedArrayToBST(nums, low, mid - 1) root.right = self._sortedArrayToBST(nums, mid + 1, high) return root
def helper(self, start: int, end: int) -> TreeNode: if start > end: return None mid = (start + end) // 2 left_child: TreeNode = self.helper(start, mid - 1) parent = TreeNode(self.list.val) # 按顺序读取链表中的元素并插入树 parent.left = left_child self.list = self.list.next parent.right = self.helper(mid + 1, end) return parent
def insert_node(root: TreeNode, parent: TreeNode, data: int): if not root: return TreeNode(data, parent=parent) if data < root.data: root.left = insert_node(root.left, root, data) else: root.right = insert_node(root.right, root, data) return root
def post_dfs(stop): if postorder and inorder[-1] != stop: root = TreeNode(postorder.pop()) root.right = post_dfs(root.val) inorder.pop() root.left = post_dfs(stop) return root
def buildTree(self, inorder, postorder): """ :type inorder: List[int] :type postorder: List[int] :rtype: TreeNode """ if (not inorder) or (not postorder): return None root, i = TreeNode(postorder[-1]), inorder.index(postorder[-1]) root.left = self.buildTree(inorder[:i], postorder[:i]) root.right = self.buildTree(inorder[i + 1:], postorder[i:-1]) return root
def build(low, high): if low > high: return None root = TreeNode(postorder.pop()) mid = inorder_dict[root.val] root.right = build(mid + 1, high) root.left = build(low, mid - 1) return root
def __init__(self, value): if isinstance(value, TreeNode): self.root = value elif type(value) in {set, frozenset}: lst = sorted(value) self.root = self.__init_bst(lst) elif hasattr(value, '__iter__'): lst = sorted(set(value)) self.root = self.__init_bst(lst) else: self.root = TreeNode(value)
def buildTree(self, preorder, inorder): """ :type preorder: List[int] :type inorder: List[int] :rtype: TreeNode """ if (not preorder) or (not inorder): return None root, i = TreeNode(preorder[0]), inorder.index(preorder[0]) root.left = self.buildTree(preorder[1:i + 1], inorder[:i]) root.right = self.buildTree(preorder[i + 1:], inorder[i + 1:]) return root
def test_giant_deserialize_preorder_inorder(giant_tree): """Writes the tree into two files and checks if they can be read back to create the same tree.""" giant_tree.save_to_disk("giant_tree") deserialized_tree = TreeNode.parse_files(preorder="giant_tree.preorder", inorder="giant_tree.inorder") assert isinstance(deserialized_tree, TreeNode) assert TreeNode.traverse(deserialized_tree) == TreeNode.traverse( giant_tree)
def build_bt(inorder, postorder): if not inorder or not postorder: return None root = TreeNode(postorder.pop()) # modifies "postorder" r = inorder.index(root.val) # O(n) time root.right = build_bt(inorder[r + 1:], postorder) # O(n) time and extra space root.left = build_bt(inorder[:r], postorder) # O(n) time and extra space return root
def Deserialize(self, s): if s is None or len(s) == 0 or self.index >= len(s): return None num = s[self.index] if s[self.index] == '$' else int(s[self.index]) self.index += 2 if num != '$': root = TreeNode(num) root.left = self.Deserialize(s) root.right = self.Deserialize(s) return root return None
def _add_node_to_tree(self, node, data): if data < node.data: if node.left: self._add_node_to_tree(node.left, data) else: node.left = TreeNode(data) return else: if node.right: self._add_node_to_tree(node.right, data) else: node.right = TreeNode(data) return