Я создаю пустое полное двоичное дерево определенной высоты в реализации массива, где все узлы в настоящее время содержат None в качестве значения.

Как бы я ввел в список значений, чтобы при печати в обход по порядку список значений был перевернут?

Примере:

create_empty_bt(height=3) # total nodes = 2^h - 1
values = [7, 6, 5, 4, 3, 2, 1]
index = 0

enter_values(index, values, root)
print_tree_postorder(root, lst)
[1, 2, 3, 4, 5, 6, 7] # output

Мой код пока напечатает: [Нет, Нет, Нет, Нет, 5, 6, 7]

class Node:
    def __init__(self, v):
        self.value = v
        self.left = None
        self.right = None


def create_empty_bt(height): # create complete binary tree
    nodes = [i for i in range(2 ** height - 1, 0, -1)]
    for i in range(height):
        start = (2 ** i) - 1
        end = (2 ** (i + 1)) - 1
        for j in range(start, end):
            nodes[j] = Node(None)
            if j == 0:
                continue
            if (j % 2) == 0:
                parent = (j - 2) // 2 # right child node
                nodes[parent].right = nodes[j]
            else:
                parent = (j - 1) // 2 # left child node
                nodes[parent].left = nodes[j]
    return nodes[0]

# Postorder = L R V, Reverse = V R L
def enter_values(index, values, root):
    if root:
        if root.value is None:
            root.value = values[index]
            enter_values(index + 1, values, root.right)
        else:
            enter_values(index + 1, values, root.left)

def print_tree(node, lst): # postorder
    if node:
        print_tree(node.left, lst)
        print_tree(node.right, lst)
        lst.append(node.value)

Заранее спасибо!

0
Kevin Yau 20 Дек 2019 в 20:34

1 ответ

Лучший ответ

Вы делаете это немного сложнее, чем нужно. Предположим, что сбалансированное дерево высоты h - это дерево с двумя дочерними элементами высоты h - 1. Имея это в виду, вы можете создать дерево со значениями None просто с помощью:

class Node:
    def __init__(self, v):
        self.value = v
        self.left = None
        self.right = None

def create_empty_bt(height):
    if height == 0:
        return None
    n = Node(None)
    n.left = create_empty_bt(height - 1) 
    n.right = create_empty_bt(height -1)
    return n

Чтобы выполнить обход после заказа, вы просто вызываете функцию для детей в правильном порядке:

def po_traverse(node):
    if node is None:
        return
    yield from po_traverse(node.left) 
    yield from po_traverse(node.right) 
    yield node.value

Это возвращает генератор, чтобы получить список, просто спросите:

list(po_traverse(node))

Чтобы вставить, вы используете ту же технику и устанавливаете значение узла в последний элемент списка, когда рекурсия раскручивается:

def insertList(node, l):
    if node is None: 
        return 
    insertList(node.left, l)
    insertList(node.right, l)
    node.value = l.pop()

Примечание: этот список используется. Вы можете избежать этого, скопировав его или переписав функцию так, чтобы она возвращала фрагмент списка при его раскручивании - но я подумал, что это показало структуру более четко.

Использование этого дает вам:

> t = create_empty_bt(height=3) # total nodes = 2^h - 1
> list(po_traverse(t))
[None, None, None, None, None, None, None]

> insertList(t, [7, 6, 5, 4, 3, 2, 1])
> list(po_traverse(t))
[1, 2, 3, 4, 5, 6, 7]
1
Mark Meyer 20 Дек 2019 в 18:51