Day-Stout-Warren-algoritmus
Kiejtés
- IPA: [ ˈdɒiʃtoutvɒrːɛnɒlɡoritmuʃ]
Főnév
Day-Stout-Warren (DSW) algoritmus
A Day-Stout-Warren (DSW) algoritmus egy hatékony módszer bináris keresőfák kiegyensúlyozására. Az algoritmust Colin Day és John Stout fejlesztette ki 1979-ben, és célja, hogy egy tetszőleges bináris keresőfát (BST) alakítson át egy kiegyensúlyozott bináris keresőfává.
Motiváció
Egy kiegyensúlyozatlan bináris keresőfa legrosszabb esetben lineáris szerkezetűvé válhat (például ha a fa lényegében egy láncot alkot). Ebben az esetben az alapműveletek – keresés, beszúrás, törlés – időbonyolultsága ( O(n) ) lehet, ahol ( n ) a csomópontok száma. Egy kiegyensúlyozott bináris keresőfában ezek az időbonyolultságok ( O(n) )-re csökkennek.
A DSW algoritmus előnye, hogy:
- Nem igényel extra memóriát (in-place kiegyensúlyozás),
- Kiegyensúlyozásának időbonyolultsága ( O(n) ).
Működési elv
A DSW algoritmus két fő lépésből áll:
- “Fa-vonal” alakzat létrehozása (Tree-to-Vine):
- A bináris keresőfát egy “láncszerű” struktúrává alakítjuk úgy, hogy minden csomópontnak csak a jobb gyereke legyen.
- Ez történeti sorrendben átalakítja a fát egy sorozatosan jobbra hajló “vonal”-fává.
- Kiegyensúlyozott fa létrehozása (Vine-to-Tree):
- A láncszerű szerkezetet újra strukturáljuk úgy, hogy az egy teljesen kiegyensúlyozott bináris keresőfát eredményezzen.
- Ehhez forgatásokat alkalmazunk, hogy a csomópontokat a megfelelő szintekre helyezzük.
Lépések részletezése
1. Fa-vonal alakzat létrehozása (Tree-to-Vine)
- Bal gyermekek folyamatos eltávolítása jobb oldali elforgatásokkal.
- Minden bal gyermek felfelé kerül a jobb oldalra.
2. Kiegyensúlyozott fa létrehozása (Vine-to-Tree)
- A láncszerű fát bal oldali elforgatásokkal alakítjuk vissza kiegyensúlyozott bináris keresőfává.
- A forgatásokat úgy végezzük el, hogy a fa minél teljesebb legyen (a lehető legjobban kitöltött fa).
Algoritmus implementációja
Python Implementáció
class Node:
"""Bináris fa csomópont osztálya."""
def __init__(self, key):
self.key = key
self.left = None
self.right = None
def right_rotate(grandparent, parent):
"""Jobb oldali forgatás."""
temp = parent.left
parent.left = temp.right
temp.right = parent
grandparent.right = temp
def left_rotate(grandparent, parent):
"""Bal oldali forgatás."""
temp = parent.right
parent.right = temp.left
temp.left = parent
grandparent.right = temp
def tree_to_vine(root):
"""A bináris keresőfát láncszerűvé alakítja (Tree-to-Vine)."""
grandparent = Node(None)
grandparent.right = root
tail = grandparent
rest = tail.right
while rest:
if rest.left:
right_rotate(tail, rest)
rest = tail.right
else:
tail = rest
rest = rest.right
return grandparent.right
def vine_to_tree(root, size):
"""A láncszerű fát kiegyensúlyozott fává alakítja (Vine-to-Tree)."""
grandparent = Node(None)
grandparent.right = root
m = 2 ** (size.bit_length() - 1) - 1 # Teljes fa mérete
make_rotations(grandparent, size - m)
while m > 1:
m //= 2
make_rotations(grandparent, m)
return grandparent.right
def make_rotations(grandparent, count):
"""Segédfüggvény a forgatások elvégzéséhez."""
parent = grandparent.right
for _ in range(count):
if parent.right:
left_rotate(grandparent, parent)
parent = grandparent.right
grandparent = parent
parent = parent.right
def dsw_balance_tree(root):
"""A teljes DSW algoritmus."""
# Tree-to-Vine lépés
size = count_nodes(root)
root = tree_to_vine(root)
# Vine-to-Tree lépés
root = vine_to_tree(root, size)
return root
def count_nodes(node):
"""Rekurzívan megszámolja a fa csomópontjait."""
if not node:
return 0
return 1 + count_nodes(node.left) + count_nodes(node.right)
def inorder_traversal(node):
"""Bejárja a fát inorder sorrendben."""
if node:
inorder_traversal(node.left)
print(node.key, end=" ")
inorder_traversal(node.right)
# Példa használat
root = Node(10)
root.left = Node(5)
root.right = Node(20)
root.left.left = Node(3)
root.left.right = Node(7)
root.right.left = Node(15)
root.right.right = Node(25)
print("Eredeti fa (inorder):")
inorder_traversal(root)
print()
# DSW kiegyensúlyozás
balanced_root = dsw_balance_tree(root)
print("Kiegyensúlyozott fa (inorder):")
inorder_traversal(balanced_root)
Kimenet
Eredeti fa (inorder): 3 5 7 10 15 20 25 Kiegyensúlyozott fa (inorder): 3 5 7 10 15 20 25
Algoritmus idő- és tárbonyolultsága
- Időbonyolultság: ( O(n) ), ahol ( n ) a fa csomópontjainak száma.
- Tárbonyolultság: ( O(1) ), mert a fa in-place kerül átalakításra (nem használ további memóriát).
Összefoglalás
- Day-Stout-Warren algoritmus célja: A bináris keresőfa kiegyensúlyozása.
- Fő lépések:
- Tree-to-Vine: A fát láncszerűvé alakítja.
- Vine-to-Tree: A láncszerű fából kiegyensúlyozott fát épít.
- Előnyök:
- Egyszerű és hatékony ( O(n) )-es időbonyolultsággal.
- In-place működik, nem igényel extra memóriát.
- Alkalmazás: Olyan esetekben használható, ahol egy bináris keresőfát utólag kell kiegyensúlyozni.
Ez az algoritmus hatékony alternatíva az AVL- vagy piros-fekete fák folyamatos kiegyensúlyozásához.
Fordítások
- Day-Stout-Warren-algoritmus - Értelmező szótár (MEK)
- Day-Stout-Warren-algoritmus - Etimológiai szótár (UMIL)
- Day-Stout-Warren-algoritmus - Szótár.net (hu-hu)
- Day-Stout-Warren-algoritmus - DeepL (hu-de)
- Day-Stout-Warren-algoritmus - Яндекс (hu-ru)
- Day-Stout-Warren-algoritmus - Google (hu-en)
- Day-Stout-Warren-algoritmus - Helyesírási szótár (MTA)
- Day-Stout-Warren-algoritmus - Wikidata
- Day-Stout-Warren-algoritmus - Wikipédia (magyar)