簡體   English   中英

調整construct() function

[英]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
  • Go 從右到左
    • 從頭開始
    • 一路遞減 pIndex
    • 從相反方向更新 pIndex
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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM