Я создаю пустое полное двоичное дерево определенной высоты в реализации массива, где все узлы в настоящее время содержат 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)
Заранее спасибо!
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]
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.