TreeLib: opraveny rotace
This commit is contained in:
parent
15449ae24b
commit
7e7303a50f
1 changed files with 42 additions and 20 deletions
|
@ -3,6 +3,7 @@ from django.db import transaction
|
||||||
# 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)
|
# 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)
|
||||||
# TODO: Chceme, aby všechno nějak zvládlo None jako parametr.
|
# TODO: Chceme, aby všechno nějak zvládlo None jako parametr.
|
||||||
|
# TODO: Do nějakých consistency-checků přidat hledání polo-sirotků (kteří nesplňují invarianty)
|
||||||
|
|
||||||
# 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):
|
||||||
|
@ -347,55 +348,76 @@ def swap_pred(node):
|
||||||
|
|
||||||
# Rotace stromu
|
# Rotace stromu
|
||||||
# Dokumentace viz wiki:
|
# Dokumentace viz wiki:
|
||||||
# (lower bude jednoduchá rotace, ne mega, existence jednoduché rotace mi došla až po nakreslení obrázku)
|
|
||||||
def raise_node(node):
|
def raise_node(node):
|
||||||
if node is None:
|
if node is None:
|
||||||
raise TreeLibError("Nelze přesunout None. Tohle by se nemělo stát.")
|
raise TreeLibError("Nelze přesunout None. Tohle by se nemělo stát.")
|
||||||
# Pojmenování viz WIKI (as of 2020-03-19 01:33:44 GMT+1)
|
# Pojmenování viz WIKI (as of 2020-03-19 01:33:44 GMT+1)
|
||||||
# FIXME: Velmi naivní, chybí error checky
|
# FIXME: Trochu méně naivní, nevěřím tomu, prosím otestovat
|
||||||
D = node
|
D = node
|
||||||
C = get_parent(D)
|
C = get_parent(D)
|
||||||
E = C.succ
|
if C is None:
|
||||||
subtree4_head = D.first_child
|
raise TreeLibError("Nelze povýšit vrchol, jenž nemá otce.")
|
||||||
subtree4_tail = last_brother(subtree4_head)
|
E = C.succ # Může být None a ničemu to nevadí
|
||||||
subtree3P_head = D.succ
|
subtree4_head = D.first_child # Může být None, ale pak se musí z 3P udělat přímo potomek D
|
||||||
subtree3L_head = C.first_child
|
subtree4_tail = last_brother(subtree4_head) # Měl by být None právě když je sub4_head=None
|
||||||
subtree3L_tail = safe_pred(D)
|
subtree3P_head = D.succ # Může být None a ničemu to nevadí
|
||||||
|
subtree3L_tail = safe_pred(D) # Pokud je None, D je první syn C a C má tedy skončit bezdětný
|
||||||
|
|
||||||
# Prostor pro motlitbu...
|
# Prostor pro motlitbu...
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Amen.
|
# Amen.
|
||||||
C.succ = D
|
# Teď už nesmíme spadnout, protože jinak skončíme se stromem v nekonzistentním stavu
|
||||||
|
C.succ = D # Nespadne
|
||||||
C.save()
|
C.save()
|
||||||
D.succ = E
|
D.succ = E # Nespadne
|
||||||
D.save()
|
D.save()
|
||||||
subtree3L_tail.succ = None
|
|
||||||
subtree3L_tail.save()
|
if subtree3L_tail is not None:
|
||||||
subtree4_tail.succ = subtree3P.head
|
subtree3L_tail.succ = None
|
||||||
subtree4_tail.save()
|
subtree3L_tail.save()
|
||||||
|
else:
|
||||||
|
assert C.first_child is D
|
||||||
|
C.first_child = None
|
||||||
|
C.save()
|
||||||
|
|
||||||
|
if subtree4_tail is not None:
|
||||||
|
subtree4_tail.succ = subtree3P_head
|
||||||
|
subtree4_tail.save()
|
||||||
|
else:
|
||||||
|
D.first_child = subtree3P_head
|
||||||
|
D.save()
|
||||||
|
|
||||||
# To by mělo být všechno...
|
# To by mělo být všechno...
|
||||||
|
|
||||||
|
# (lower bude jednoduchá rotace, ne mega, existence jednoduché rotace mi došla až po nakreslení obrázku)
|
||||||
def lower_node(node):
|
def lower_node(node):
|
||||||
if node is None:
|
if node is None:
|
||||||
raise TreeLibError("Nelze přesunout None. Tohle by se nemělo stát.")
|
raise TreeLibError("Nelze přesunout None. Tohle by se nemělo stát.")
|
||||||
# Pojmenování viz WIKI (as of 2020-03-19 01:33:44 GMT+1)
|
# Pojmenování viz WIKI (as of 2020-03-19 01:33:44 GMT+1)
|
||||||
# FIXME: Velmi naivní, chybí error checky
|
# FIXME: Velmi naivní, chybí error checky
|
||||||
C = node
|
C = node
|
||||||
D = C.succ
|
D = C.succ # Může být None a ničemu to nevadí
|
||||||
B = safe_pred(C)
|
B = safe_pred(C)
|
||||||
subtree2_head = B.first_child
|
if B is None:
|
||||||
subtree2_tail = last_brother(subtree2_head)
|
raise TreeLibError("Nelze ponížit prvního syna (není pod co)")
|
||||||
|
subtree2_head = B.first_child # Je-li None, pak se z C má stát první syn
|
||||||
|
subtree2_tail = last_brother(subtree2_head) # None iff head=None, doufám
|
||||||
|
|
||||||
# Prostor pro motlitbu...
|
# Prostor pro motlitbu...
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Amen.
|
# Amen.
|
||||||
B.succ = D
|
# Teď už nesmíme spadnout, protože jinak skončíme se stromem v nekonzistentním stavu
|
||||||
|
B.succ = D # Nespadne
|
||||||
B.save()
|
B.save()
|
||||||
subtree2_tail.succ = C
|
if subtree2_tail is not None:
|
||||||
subtree2_tail.save()
|
subtree2_tail.succ = C
|
||||||
|
subtree2_tail.save()
|
||||||
|
else:
|
||||||
|
assert subtree2_head is None
|
||||||
|
B.first_child = C
|
||||||
|
B.save()
|
||||||
|
|
||||||
# To by mělo být všechno...
|
# To by mělo být všechno...
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue