|
@ -1,4 +1,6 @@ |
|
|
|
|
|
from django.core.exceptions import ObjectDoesNotExist |
|
|
# NOTE: node.prev a node.succ jsou implementovány přímo v models.TreeNode |
|
|
# NOTE: node.prev a node.succ jsou implementovány přímo v models.TreeNode |
|
|
|
|
|
# TODO: Všechny tyto funkce se naivně spoléhají na to, že jako parametr dostanou nějaký TreeNode (některé možná zvládnou i None) |
|
|
|
|
|
|
|
|
# Slouží k debugování pro rychlé získání představy o podobě podstromu pod tímto TreeNode. |
|
|
# Slouží k debugování pro rychlé získání představy o podobě podstromu pod tímto TreeNode. |
|
|
def print_tree(node,indent=0): |
|
|
def print_tree(node,indent=0): |
|
@ -9,23 +11,69 @@ def print_tree(node,indent=0): |
|
|
if node.succ: |
|
|
if node.succ: |
|
|
print_tree(node.succ, indent=indent) |
|
|
print_tree(node.succ, indent=indent) |
|
|
|
|
|
|
|
|
|
|
|
# Django je trošku hloupé, takže node.prev nevrací None, ale hází django.core.exceptions.ObjectDoesNotExist |
|
|
|
|
|
def safe_pred(node): |
|
|
|
|
|
try: |
|
|
|
|
|
return node.prev |
|
|
|
|
|
except ObjectDoesNotExist: |
|
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
# A to samé pro .father_of_first |
|
|
|
|
|
def safe_father_of_first(node): |
|
|
|
|
|
return node.prev |
|
|
|
|
|
except ObjectDoesNotExist: |
|
|
|
|
|
return None |
|
|
|
|
|
|
|
|
## Rodinné vztahy |
|
|
## Rodinné vztahy |
|
|
def get_parent(node): |
|
|
def get_parent(node): |
|
|
pass |
|
|
|
|
|
# Nejdřív získáme prvního potomka... |
|
|
# Nejdřív získáme prvního potomka... |
|
|
|
|
|
while safe_pred(node) is not None: |
|
|
|
|
|
node = safe_pred(node) |
|
|
# ... a z prvního potomka umíme najít rodiče |
|
|
# ... a z prvního potomka umíme najít rodiče |
|
|
|
|
|
return safe_father_of_first(node) |
|
|
|
|
|
|
|
|
# Obecný next: další Node v "the-right-order" pořadí (já, pak potomci, pak sousedé) |
|
|
# Obecný next: další Node v "the-right-order" pořadí (já, pak potomci, pak sousedé) |
|
|
def general_next(node): |
|
|
def general_next(node): |
|
|
pass |
|
|
# Máme potomka? |
|
|
def general_prev(node): |
|
|
if node.first_child is not None: |
|
|
pass |
|
|
return node.first_child |
|
|
|
|
|
# Nemáme potomka. |
|
|
|
|
|
# Chceme najít následníka sebe, nebo některého (toho nejblíž příbuzného) z našich předků (tatínka, dědečka, ...) |
|
|
|
|
|
while node.succ is None: |
|
|
|
|
|
node = get_parent(node) |
|
|
|
|
|
if node is None: |
|
|
|
|
|
return None # žádný z předků nemá následníka, takže žádny vrchol nenásleduje. |
|
|
|
|
|
return node.succ |
|
|
|
|
|
|
|
|
|
|
|
def last_brother(node): |
|
|
|
|
|
while node.succ is not None: |
|
|
|
|
|
node = node.succ |
|
|
|
|
|
return node |
|
|
|
|
|
|
|
|
# Generátor potomků |
|
|
def general_prev(node): |
|
|
# TODO: copy-pasta |
|
|
# Předchůdce je buď rekurzivně poslední potomek předchůdce, nebo náš otec. |
|
|
|
|
|
# Otce vyřešíme nejdřív: |
|
|
|
|
|
if safe_pred(node) is None: |
|
|
|
|
|
return safe_father_of_first(node) |
|
|
|
|
|
pred = safe_pred(node) |
|
|
|
|
|
while pred.first_child is not None: |
|
|
|
|
|
pred = last_brother(pred.first_child) |
|
|
|
|
|
# pred nyní nemá žádné potomky, takže je to poslední rekurzivní potomek původního předchůdce |
|
|
|
|
|
return pred |
|
|
|
|
|
|
|
|
# Generátor bratrů |
|
|
# Generátor bratrů |
|
|
|
|
|
# Generátor potomků níže spoléhá na to, že se tohle dá volat i s parametrem None. |
|
|
|
|
|
def all_brothers(node): |
|
|
|
|
|
current = node |
|
|
|
|
|
while current is not None: |
|
|
|
|
|
yield current |
|
|
|
|
|
current = current.succ |
|
|
|
|
|
|
|
|
|
|
|
# Generátor potomků |
|
|
|
|
|
def all_children(node): |
|
|
|
|
|
brothers = all_brothers(node.first_child) |
|
|
|
|
|
for br in brothers: |
|
|
|
|
|
yield br |
|
|
|
|
|
|
|
|
# Generátor následníků v "the-right-order" |
|
|
# Generátor následníků v "the-right-order" |
|
|
|
|
|
|
|
|