[英]Adjust construct() function
class Node:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
def construct(start, end, preorder, pIndex, dict):
# base case
if start > end:
return None, pIndex
root = Node(preorder[pIndex])
pIndex = pIndex + 1
index = dict[root.data]
root.left, pIndex = construct(start, index - 1, preorder, pIndex, dict)
root.right, pIndex = construct(index + 1, end, preorder, pIndex, dict)
return root, pIndex
def constructTree(inorder, preorder):
dict = {}
for i, e in enumerate(inorder):
dict[e] = i
pIndex = 0
return construct(0, len(inorder) - 1, preorder, pIndex, dict)[0]
if __name__ == '__main__':
inorder = [4, 2, 1, 7, 5, 8, 3, 6]
preorder = [1, 2, 4, 3, 5, 7, 8, 6]
root = constructTree(inorder, preorder)
print("The inorder traversal is ", end='')
inorderTraversal(root)
preorderTraversal(root)
此代碼使用前序和中序遍歷構造一棵樹。 如何修改該代碼以使其適用於 inorder-postorder 和 preorder-postorder? 我想我只需要修改construct()
並以類似的方式創建constructPreOrderInOrderTree()
和constructPreOrderPostOrderTree()
。
編輯
假設我有inorder=[3, 7, 1, 10, 9, 5, 8, 6, 4, 2]
和postorder = [3, 7, 10, 9, 1, 8, 4, 6, 2, 5]
. construct()
會為 inorder-preorder 執行此操作,但它不適用於該示例。 所以我需要一個 function 的版本,它可以與 inorder-postorder 和 preorder-postorder 一起使用。
變化:
lookup
這樣的變量名稱以避免掩蓋現有類型名稱(例如dict
)def construct_post(start, end, postorder, pIndex, lookup):
# base case
if start > end or pIndex < 0:
return None, pIndex
root = Node(postorder[pIndex])
# go from the right to the left instead
pIndex = pIndex - 1
index = lookup[root.data]
# update pIndex going in the opposite direction
root.right, pIndex = construct_post(index + 1, end, postorder, pIndex, lookup)
root.left, pIndex = construct_post(start, index - 1, postorder, pIndex, lookup)
return root, pIndex
def constructTree_post(inorder, postorder):
lookup = {e: i for i, e in enumerate(inorder)}
pIndex = len(postorder) - 1
# start from the end
return construct_post(0, len(inorder) - 1, postorder, pIndex, lookup)[0]
結果樹:
1
/ \
2 3
/ / \
4 5 6
/ \
7 8
甚至沒有閱讀 Geeks-for-Geeks 頁面,我決定實現自己的構造函數算法(preorder-postorder、preorder-inorder、inorder-postorder)。
我所有的算法都是O(N^2)
復雜度。
Besides construction functions ( construct_preorder_postorder()
, construct_preorder_inorder()
, construct_inorder_postorder()
) I also implemented traversing functions ( traverse_preorder()
, traverse_inorder()
, traverse_postorder()
), console tree printing function ( print_tree()
) and Node equality comparison function ( __eq__()
)。
class Node:
def __init__(self, data, left = None, right = None):
self.data = data
self.left = left
self.right = right
def __eq__(self, other):
return (self.data == other.data and self.left == other.left and
self.right == other.right)
def traverse_inorder(node):
return ([] if node is None else
traverse_inorder(node.left) + [node.data] + traverse_inorder(node.right))
def traverse_preorder(node):
return ([] if node is None else
[node.data] + traverse_preorder(node.left) + traverse_preorder(node.right))
def traverse_postorder(node):
return ([] if node is None else
traverse_postorder(node.left) + traverse_postorder(node.right) + [node.data])
def construct_preorder_postorder(pre, post):
assert sorted(pre) == sorted(post) and len(pre) == len(set(pre)), (pre, post)
if len(pre) == 0:
return None
if len(pre) == 1:
return Node(pre[0])
root, l = pre[0], pre[1]
for i, e in enumerate(post):
if e == l:
ls = i + 1
rs = len(post) - 1 - ls
break
return Node(root,
None if ls == 0 else construct_preorder_postorder(pre[1:1 + ls], post[:ls]),
None if rs == 0 else construct_preorder_postorder(pre[-rs:], post[-1 - rs:-1]))
def construct_preorder_inorder(pre, ino):
assert sorted(pre) == sorted(ino) and len(pre) == len(set(pre)), (pre, ino)
if len(pre) == 0:
return None
if len(pre) == 1:
return Node(pre[0])
root, l = pre[0], pre[1]
for i, e in enumerate(ino):
if e == root:
ls = i
rs = len(ino) - 1 - ls
break
return Node(root,
None if ls == 0 else construct_preorder_inorder(pre[1:1 + ls], ino[:ls]),
None if rs == 0 else construct_preorder_inorder(pre[-rs:], ino[-rs:]))
def construct_inorder_postorder(ino, post):
assert sorted(ino) == sorted(post) and len(ino) == len(set(ino)), (ino, post)
if len(post) == 0:
return None
if len(post) == 1:
return Node(post[0])
root, r = post[-1], post[-2]
for i, e in enumerate(ino):
if e == root:
ls = i
rs = len(ino) - 1 - ls
break
return Node(root,
None if ls == 0 else construct_inorder_postorder(ino[:ls], post[:ls]),
None if rs == 0 else construct_inorder_postorder(ino[-rs:], post[-1 - rs:-1]))
def print_tree(node):
def inner(node, *, upref = '', cpref = '', dpref = ''):
if node is None:
return
inner(node.right, upref = dpref + ' |',
cpref = dpref + ' /', dpref = dpref + ' ')
print(cpref + '--' + str(node.data))
inner(node.left, upref = upref + ' ',
cpref = upref + ' \\', dpref = upref + ' |')
inner(node)
if __name__ == '__main__':
node = Node(1, Node(2, Node(4)), Node(3, Node(5, Node(7), Node(8)), Node(6)))
print_tree(node)
preorder, inorder, postorder = (
traverse_preorder(node), traverse_inorder(node), traverse_postorder(node))
preorder_cons, inorder_cons, postorder_cons = (
construct_preorder_postorder(preorder, postorder),
construct_preorder_inorder(preorder, inorder),
construct_inorder_postorder(inorder, postorder),
)
assert preorder_cons == inorder_cons == postorder_cons
Output:
/--6
/--3
| | /--8
| \--5
| \--7
--1
\--2
\--4
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.