Código de pitón para árbol almacenado en 1d Array contiene error lógico relativo a puntero de nodo derecho
En el siguiente código de un libro de texto de CS estoy utilizando, en la salida para el árbol después de insertar el valor 32
, el RightPointer
para el nodo en posición de matriz 0
se establece 3
. Esto no tiene sentido para mí ya que pensé que todavía debería ser 2
.
Parece que el código es incorrecto, ya que hay dos nodos con un RightPointer
de 3
Ahora. ¿Puede alguien por favor explicar lo que necesito hacer para hacer que el código funcione correctamente?
Supongo que esta línea es la culpable: tree[PreviousNodePtr].RightPointer = NewNodePtr
como es ahí donde RightPointer
actualizaciones, pero no puedo ver cómo lo cambiaría para evitar el problema.
# NULL should be set to -1 if using array element with index 0
NULL = -1
# Declare record type to store data and pointer
class TreeNode:
def __init__(self):
self.Data = ""
self.LeftPointer = NULL
self.RightPointer = NULL
def print_tree(tree):
print("{0:^5}|{1:^10}|{2:^10}|{3:^10}|".format("", "Left", "Data", "Right"))
for i in range(len(tree)):
index = "[" + str(i) + "]"
print("{0:^5}|{1:^10}|{2:^10}|{3:^10}|".format(index, tree[i].LeftPointer, tree[i].Data, tree[i].RightPointer))
print("RootPointer", RootPointer, "FreePtr", FreePtr, "\n")
def InsertNode(tree, NewItem):
global RootPointer, FreePtr
if FreePtr == NULL:
# tree is full
print("Tree is full")
return
# There is space in the array
# Take node from free list and store data item
NewNodePtr = FreePtr
tree[NewNodePtr].Data = NewItem
FreePtr = tree[FreePtr].LeftPointer
tree[NewNodePtr].LeftPointer = NULL
# check if empty tree
if RootPointer == NULL:
# insert new node at root
RootPointer = NewNodePtr
else: # find insertion point
ThisNodePtr = RootPointer
while ThisNodePtr != NULL: # while not a leaf node
PreviousNodePtr = ThisNodePtr # remember this node
if tree[ThisNodePtr].Data > NewItem:
TurnedLeft = True # # follow left pointer
ThisNodePtr = tree[ThisNodePtr].LeftPointer
else:
TurnedLeft = False
ThisNodePtr = tree[ThisNodePtr].RightPointer
if TurnedLeft:
tree[PreviousNodePtr].LeftPointer = NewNodePtr
else:
tree[PreviousNodePtr].RightPointer = NewNodePtr
tree = [TreeNode() for i in range(5)]
RootPointer = NULL # set Root pointer
FreePtr = 0 # set starting position of list
for i in range(len(tree) - 1): # link all nodes to make free list
tree[i].LeftPointer = i + 1
print_tree(tree)
InsertNode(tree, 10)
print_tree(tree)
InsertNode(tree, 5)
print_tree(tree)
InsertNode(tree, 20)
print_tree(tree)
InsertNode(tree, 32)
print_tree(tree)
Producto:
| Left | Data | Right |
[0] | 1 | | -1 |
[1] | 2 | | -1 |
[2] | 3 | | -1 |
[3] | 4 | | -1 |
[4] | -1 | | -1 |
RootPointer -1 FreePtr 0
| Left | Data | Right |
[0] | -1 | 10 | -1 |
[1] | 2 | | -1 |
[2] | 3 | | -1 |
[3] | 4 | | -1 |
[4] | -1 | | -1 |
RootPointer 0 FreePtr 1
| Left | Data | Right |
[0] | 1 | 10 | -1 |
[1] | -1 | 5 | -1 |
[2] | 3 | | -1 |
[3] | 4 | | -1 |
[4] | -1 | | -1 |
RootPointer 0 FreePtr 2
| Left | Data | Right |
[0] | 1 | 10 | 2 |
[1] | -1 | 5 | -1 |
[2] | -1 | 20 | -1 |
[3] | 4 | | -1 |
[4] | -1 | | -1 |
RootPointer 0 FreePtr 3
| Left | Data | Right |
[0] | 1 | 10 | 3 |
[1] | -1 | 5 | -1 |
[2] | -1 | 20 | 3 |
[3] | -1 | 32 | -1 |
[4] | -1 | | -1 |
RootPointer 0 FreePtr 4
Pregunta hecha hace 3 años, 4 meses, 28 días - Por quantumcoder403a
3 Respuestas:
-
El problema es que no estás actualizando tu
ThisNodePtr
. Así que...ThisNodePtr
El puntero no se mueve a la izquierda o a la derecha y por lo tanto siempre actualiza la raíz izquierda o derecha.if TurnedLeft: if tree[PreviousNodePtr].LeftPointer != NULL: PreviousNodePtr = ThisNodePtr ThisNodePtr = tree[ThisNodePtr].LeftPointer tree[PreviousNodePtr].LeftPointer = NewNodePtr else: tree[PreviousNodePtr].LeftPointer = NewNodePtr else: if tree[PreviousNodePtr].RightPointer != NULL: PreviousNodePtr = ThisNodePtr ThisNodePtr = tree[ThisNodePtr].RightPointer tree[PreviousNodePtr].RightPointer = NewNodePtr else: tree[PreviousNodePtr].RightPointer = NewNodePtr
Puedes probarlo con
InsertNode(tree, 3)
en lugar deInsertNode(tree, 32)
También si quieres. Se moverá a la izquierda cuando el nodo izquierdo no seaNULL
.Respondida el Dec 17, 2020 a las 16:02 - por codemaestro
Votos positivos: 0 | Votos negativos: 0 -
El error en el código se encuentra en la forma en que se actualiza
RightPointer
en el árbol cuando se inserta un nuevo nodo. El problema radica en que todas las veces que se actualizaRightPointer
, se está asignando el valor deNewNodePtr
directamente, lo cual no es correcto.Para corregir este problema, necesitas asegurarte de seguir la estructura correcta de un árbol binario de búsqueda cuando se inserta un nuevo nodo. Esto implica encontrar el lugar correcto para insertar el nuevo nodo y ajustar los punteros de manera adecuada.
Aquí te dejo la corrección que debes realizar en la función
InsertNode
para actualizar correctamente los punterosRightPointer
al insertar un nuevo nodo:python def InsertNode(tree, NewItem): global RootPointer, FreePtr if FreePtr == NULL:
tree is full
print("Tree is full") returnThere is space in the array
Take node from free list and store data item
NewNodePtr = FreePtr tree[NewNodePtr].Data = NewItem FreePtr = tree[FreePtr].LeftPointer tree[NewNodePtr].LeftPointer = NULL if RootPointer == NULL:insert new node at root
RootPointer = NewNodePtr else: ThisNodePtr = RootPointer PreviousNodePtr = NULL while ThisNodePtr != NULL: PreviousNodePtr = ThisNodePtrremember this node
if tree[ThisNodePtr].Data > NewItem: TurnedLeft = True ThisNodePtr = tree[ThisNodePtr].LeftPointer else: TurnedLeft = False ThisNodePtr = tree[ThisNodePtr].RightPointer if TurnedLeft: tree[PreviousNodePtr].LeftPointer = NewNodePtr else: tree[PreviousNodePtr].RightPointer = NewNodePtr tree = [TreeNode() for i in range(5)] RootPointer = NULLset Root pointer
FreePtr = 0set starting position of list
for i in range(len(tree)-1):link all nodes to make free list
tree[i].LeftPointer = i+1 print_tree(tree) InsertNode(tree, 10) print_tree(tree) InsertNode(tree, 5) print_tree(tree) InsertNode(tree, 20) print_tree(tree) InsertNode(tree, 32) print_tree(tree)Con estas modificaciones, deberías tener una correcta inserción de nodos en el árbol y los punteros
RightPointer
deberían actualizarse de manera adecuada en función de la lógica de un árbol binario de búsqueda.Respondida el Dec 18, 2020 a las 15:59 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Tienes razón, el código proporcionado tiene un error lógico en la actualización del puntero derecho del nodo. Cuando se inserta un nuevo nodo en el árbol, su puntero derecho debe actualizarse al puntero derecho del nodo padre si se inserta a la derecha y a NULL si se inserta a la izquierda.
La línea que causa el error es:
python tree[PreviousNodePtr].RightPointer = NewNodePtr
Debería cambiarse a:
python if TurnedLeft: tree[PreviousNodePtr].LeftPointer = NewNodePtr else: tree[PreviousNodePtr].RightPointer = NewNodePtr
Así es como funciona el código corregido:
Cuando se inserta un nuevo nodo, se asigna el puntero izquierdo o derecho del nodo padre al nuevo nodo, según la dirección tomada. Si el nuevo nodo se inserta a la izquierda, el puntero izquierdo del nodo padre se actualiza al nuevo nodo.
- Si el nuevo nodo se inserta a la derecha, el puntero derecho del nodo padre se actualiza al nuevo nodo.
Esto garantiza que el árbol binario se construya correctamente y que los punteros izquierdo y derecho se actualicen correctamente.
Aquí está el código corregido:
python def InsertNode(tree, NewItem): global RootPointer, FreePtr if FreePtr == NULL:
tree is full
print("Tree is full") returnThere is space in the array
Take node from free list and store data item
NewNodePtr = FreePtr tree[NewNodePtr].Data = NewItem FreePtr = tree[FreePtr].LeftPointer tree[NewNodePtr].LeftPointer = NULLcheck if empty tree
if RootPointer == NULL:insert new node at root
RootPointer = NewNodePtr else:find insertion point
ThisNodePtr = RootPointer while ThisNodePtr != NULL:while not a leaf node
PreviousNodePtr = ThisNodePtrremember this node
if tree[ThisNodePtr].Data > NewItem: TurnedLeft = True# follow left pointer
ThisNodePtr = tree[ThisNodePtr].LeftPointer else: TurnedLeft = False ThisNodePtr = tree[ThisNodePtr].RightPointer if TurnedLeft: tree[PreviousNodePtr].LeftPointer = NewNodePtr else: tree[PreviousNodePtr].RightPointer = NewNodePtrEspero que esto solucione el problema con el código. Si tienes más preguntas, no dudes en preguntar.
Respondida el Dec 18, 2020 a las 16:03 - por Gemini
Votos positivos: 0 | Votos negativos: 0