Apuntes_Python/03_arbol_binario/arbol_binario.py

251 lines
6.3 KiB
Python
Raw Normal View History

2022-12-24 22:41:20 -03:00
#!/usr/bin/env python
"""
Clase Arbol Binario
"""
from collections import deque
from math import inf
import subprocess
class Nodo:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
# ./01_valores_lejanos_primero.py
def ValoresLejanosPrioridad(self):
"""
retorna valor de nodos priorizando profundidad a nivel (de izquierda a derecha)
usando recursividad y desempaquetado de lista (operador '*')
"""
if self is None:
return []
val_izq = ValoresLejanosPrioridad(self.left)
val_der = ValoresLejanosPrioridad(self.right)
return [self.val, *val_izq, *val_der]
def ValoresLejanosPrioridad2(self):
"""
retorna valor de nodos priorizando profundidad a nivel (de izquierda a derecha)
usando recursividad, sumando las listas retornadas en cada recursión
"""
if self is None:
return []
val_izq = ValoresLejanosPrioridad2(self.left)
val_der = ValoresLejanosPrioridad2(self.right)
return [self.val] + val_izq + val_der
def ValoresLejanosPrioridad3(self):
"""
retorna valor de nodos priorizando profundidad a nivel (de izquierda a derecha)
usando una lista como pila (lifo)
"""
pila = [self]
valores = []
if self == None:
return []
while pila:
actual = pila.pop()
valores.append(actual.val)
if actual.right:
pila.append(actual.right)
if actual.left:
pila.append(actual.left)
return valores
# ./02_valores_nivel_primero.py
def ValoresPrioridadNivel(self):
"""
retorna valor de nodos de un arbol binario
priorizando nivel (de izquierda a derecha)
usando una lista como cola/fila* (fifo)
*cola (from collections import deque)
"""
cola = deque([self])
valores = []
if self == None:
return []
while cola:
actual = cola.popleft()
valores.append(actual.val)
if actual.left:
cola.append(actual.left)
if actual.right:
cola.append(actual.right)
return valores
def ValoresPrioridadNivel2(self):
"""
retorna valor de nodos de un arbol binario
priorizando nivel (de izquierda a derecha)
usando una lista y pop(0)* (fifo)
*adelanta los indices un valor
"""
cola = [self]
valores = []
if self == None:
return []
while cola:
actual = cola.pop(0)
valores.append(actual.val)
if actual.left:
cola.append(actual.left)
if actual.right:
cola.append(actual.right)
return valores
# ./03_arbol_incluye.py
def ArbolIncluye(self, valor):
"""
retorna booleano según existencia en árbol binario
del valor consultado, utilizando recursión
"""
if self is None:
return False
if self.val == valor:
return True
return ArbolIncluye(self.left, valor) or ArbolIncluye(self.right, valor)
def ArbolIncluye2(self, valor):
"""
retorna booleano según existencia en árbol binario
del valor consultado utilizando una cola o fila(fifo)
"""
if self is None:
return False
cola = deque([self])
while cola:
actual = cola.popleft()
if actual.val == valor:
return True
if actual.left:
cola.append(actual.left)
if actual.right:
cola.append(actual.right)
return False
# ./04_suma_valores.py
def SumaValores(self):
"""
retorna la suma de todos los valores del árbol binario
recursivamente.
"""
if self is None:
return 0
return self.val + SumaValores(self.left) + SumaValores(self.right)
def SumaValores2(self):
"""
retorna la suma de todos los valores del árbol binario
"""
if self is None:
return 0
cola = deque([self])
suma = 0
while cola:
actual = cola.popleft()
suma += actual.val
if actual.left:
cola.append(actual.left)
if actual.right:
cola.append(actual.right)
return suma
def SumaValores3(self):
"""
retorna la suma de todos los valores del árbol binario
reutiliza la función ValoresNivelPrioridad()
"""
valores = ValoresPrioridadNivel(self)
suma_valores = sum(valores)
return suma_valores
# ./05_valor_minimo.py
def ValorMinimo(self):
"""
retorna el valor mínimo en árbol binario usando recursividad
"""
if self is None:
return inf
min_izq = ValorMinimo(self.left)
min_der = ValorMinimo(self.right)
return min(self.val, min_izq, min_der)
def ValorMinimo2(self):
"""
retorna el valor mínimo en árbol binario usando una cola/fila(fifo)
"""
minimo = inf
cola = deque([self])
while cola:
actual = cola.popleft()
if actual.val < minimo:
minimo = actual.val
if actual.left:
cola.append(actual.left)
if actual.right:
cola.append(actual.right)
return minimo
def ValorMinimo3(self):
"""
retorna el valor mínimo en árbol binario, reutiliza
funcion ValoresPrioridadNivel
"""
valores = ValoresPrioridadNivel(self)
minimo = min(valores)
return minimo
# 06_suma_mayor_rutas.py
def SumaMayorDeRutas(self):
"""
retorna la mayor suma de los valores de las rutas(root-leaf)
del árbol binario, usando recursividad
"""
if self is None:
return -inf
if self.left is None and self.right is None:
return self.val
mayor = max(SumaMayorDeRutas(self.left), SumaMayorDeRutas(self.right))
return self.val + mayor
def SumaMayorDeRutas2(self):
"""
retorna la mayor suma de los valores de las rutas(root-leaf)
del árbol binario, usando recursividad
"""
if self is None:
return float('-inf')
if self.left is None and self.right is None:
return self.val
mayor = max(SumaMayorDeRutas2(self.left), SumaMayorDeRutas2(self.right))
return self.val + mayor
if __name__ == '__main__':
subprocess.call(["python", "./01_valores_lejanos_primero.py"])
subprocess.call(["python", "./02_valores_nivel_primero.py"])
subprocess.call(["python", "./03_arbol_incluye.py"])
subprocess.call(["python", "./04_suma_valores.py"])
subprocess.call(["python", "./05_valor_minimo.py"])
subprocess.call(["python", "./06_suma_mayor_rutas.py"])