[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
TREAPS
Eu li o programa do Knuth Wordtest e nao consegui entender exatamente o
que uma Treap faz.
O que entendi foi que ele usa Heap para espalhar os dados e depois ABB
para buscar as palavras no arquivo dado, mas parece que de alguma forma o
programa monta as duas arvores ao mesmo tempo. Eh isso mesmo?
Procurei, entao na Internet algum material sobre isso. Estou deixando o
que encontrei aqui para todos os alunos verem, mas ainda nao ficou claro
como uma Treap funciona. Gostaria que alguem pudesse explicar melhor isso.
Pelo pouco que entendi ela tem um otimo desempenho em busca.
Professor, em que livro podemos encontrar alguma coisa?
Valeu turma!
Evelyn Cristina Pinto <ecp@linux.ime.usp.br>
The first part of this page is in German - please ignore it if you do not
understand it!
Idea behind Treaps
Implementation of Treaps
Implementation of the test driver
Results of the measurements
Die Idee von Treaps stammt von Aragon und Seidel (1989).
Das Ziel ist, die Balancierung von binären Suchbäumen mit möglichst geringem
Aufwand zur Verhinderung von Degeneration.
Hauptidee: Beim Einfügen von Elementen eine zufällige Priorität vergeben und
im binären Suchbaum durch Rotationen die Heapbedingung wieder herstellen.
Suchbedingung:
Linker Teilbaum enthält alle Elemente, deren Schlüssel kleiner sind.
Rechter Teilbaum enthält alle Elemente, deren Schlüssel größer sind.
Heapbedingung:
Söhne haben (numerisch) größere Priorität.
Suchen: wie in normalen binären Suchbäumen.
Einfügen:
Platz im Suchbaum suchen.
Blatt für neuen Knoten anlegen und zufällige Priorität vergeben.
Durch Rotationen (lokale Transformation, die die Suchbedingung nicht
invalidiert) die Heapbedingung wiederherstellen, indem das Element nach oben
wandert.
Entfernen:
Element suchen.
Einfaches Löschen, wenn es keinen linken oder rechten Sohn gibt.
Ansonsten Element solange durch Rotationen nach unten schieben, bis ein
Sohn NIL geworden ist. Man muß dabei aufpassen, mit welchem Sohn man
rotiert, da dieser Sohn dann nach dem Löschen der Wurzel über dem anderen
Sohn liegt. Man muß deshalb den Sohn mit der (numerisch) kleineren Priorität
nehmen, da dieser dann über dem anderen Sohn landet, womit die Heapbedingung
erfüllt ist.
MODULE Treaps; (* CS, 2 Jul 97 *)
(* Heuristically balanced search trees:
- C.R.Aragon, R.Seidel: Randomized Search Trees. Algorithmica,
16(4/5):464-497, 1996
- S. Nilsson: Treaps in Java. Dr.Dobbs Journal, July 1997, 40 - 44.
*)
IMPORT Out;
TYPE
Node* = POINTER TO NodeDesc;
NodeDesc* = RECORD
prio: INTEGER; (* node with smaller priority is higher up the tree *)
val: INTEGER;
left, right: Node
END;
VAR
seed: LONGINT;
costs: LONGINT;
PROCEDURE Random(): INTEGER;
BEGIN
seed := (seed * 27181 + 13849) MOD 65536;
RETURN SHORT(seed)
END Random;
PROCEDURE Search* (node: Node; val: INTEGER): Node;
BEGIN
IF (node = NIL) OR (node.val = val) THEN RETURN node
ELSIF val < node.val THEN RETURN Search(node.left, val)
ELSE RETURN Search(node.right, val)
END
END Search;
PROCEDURE Insert* (VAR root: Node; val: INTEGER);
VAR p: Node;
BEGIN
IF root = NIL THEN
NEW(root); root.val := val; root.prio := Random()
ELSIF val < root.val THEN
Insert(root.left, val);
IF root.prio > root.left.prio THEN p := root.left; root.left := p.right;
p.right := root; root := p END
ELSE
Insert(root.right, val);
IF root.prio > root.right.prio THEN p := root.right; root.right :=
p.left; p.left := root; root := p END
END
END Insert;
PROCEDURE Delete* (VAR root: Node; val: INTEGER);
VAR p: Node;
BEGIN
IF root # NIL THEN
IF val = root.val THEN
IF root.left = NIL THEN root := root.right; RETURN
ELSIF root.right = NIL THEN root := root.left; RETURN
ELSIF root.left.prio < root.right.prio THEN p := root.left; root.left
:= p.right; p.right := root; root := p
(* left subtree has (numerically) smaller priority, i.e. it must be
above the right subtree in
the resulting tree. Rotating the left subtree results in moving
the left node up, the right
node will be located under the left one, priority is maintained
correctly. Otherwise rotate
the right subtree so that the right node will be located above the
left node. *)
ELSE p := root.right; root.right := p.left; p.left := root; root := p
END
END;
IF val < root.val THEN Delete(root.left, val) ELSE Delete(root.right,
val) END
END
END Delete;
PROCEDURE Dump* (root: Node; indent: INTEGER);
VAR i: INTEGER;
BEGIN
FOR i := 1 TO indent DO Out.String(" ") END;
IF root = NIL THEN Out.Char("-"); Out.Ln
ELSE
Out.Int(root.val, 0); Out.Ln;
Dump(root.left, indent + 1);
Dump(root.right, indent + 1)
END
END Dump;
PROCEDURE Costs* (root: Node);
VAR nofNodes: INTEGER;
PROCEDURE Search (node: Node; val: INTEGER; VAR height: INTEGER): Node;
BEGIN
IF (node = NIL) OR (node.val = val) THEN RETURN node
ELSIF val < node.val THEN INC(height); RETURN Search(node.left, val,
height)
ELSE INC(height); RETURN Search(node.right, val, height)
END
END Search;
PROCEDURE Traverse (node: Node);
VAR height: INTEGER;
BEGIN
IF node # NIL THEN
Traverse(node.left);
Traverse(node.right);
INC(nofNodes);
height := 0;
IF Search(root, node.val, height) # NIL THEN INC(costs, LONG(height))
ELSE HALT(66)
END
END
END Traverse;
BEGIN
costs := 0; nofNodes := 0;
Traverse(root);
Out.Ln; Out.String("Costs for searching "); Out.Int(nofNodes, 0);
Out.String(": "); Out.Int(costs, 0)
END Costs;
BEGIN
seed := 20015
END Treaps.
MODULE test; (** CS, 2 Jul 97 **)
IMPORT Treaps, In, Out;
VAR
tree: Treaps.Node;
PROCEDURE Insert*;
VAR val: INTEGER;
BEGIN
In.Open;
REPEAT
In.Int(val);
Treaps.Insert(tree, val)
UNTIL ~In.Done;
Treaps.Dump(tree, 0)
END Insert;
PROCEDURE InsertMany*;
VAR no: INTEGER;
BEGIN
In.Open; In.Int(no);
IF In.Done THEN
WHILE no > 0 DO
Treaps.Insert(tree, no);
DEC(no)
END
END
END InsertMany;
PROCEDURE DeleteMany*;
VAR from, to: INTEGER;
BEGIN
In.Open; In.Int(from); In.Int(to);
IF In.Done THEN
FOR from := from TO to DO Treaps.Delete(tree, from) END
END
END DeleteMany;
PROCEDURE Delete*;
VAR val: INTEGER;
BEGIN
In.Open; In.Int(val);
Treaps.Delete(tree, val);
Treaps.Dump(tree, 0)
END Delete;
PROCEDURE Costs*;
BEGIN Treaps.Costs(tree)
END Costs;
BEGIN
tree := NIL
END test.
The results of the measurements:
test.Insert ^ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
test.InsertMany ^ 100 400
test.DeleteMany ^ 10 50 250 350
test.Delete ^
test.Costs
Batch.Start
test.InsertMany 100
test.Costs
test.DeleteMany 10 50
test.Costs
~
Costs for searching 100: 568 N * log N = 664
Costs for searching 59: 290 N * log N = 346
Batch.Start
test.InsertMany 400
test.Costs
test.DeleteMany 250 350
test.Costs
~
Costs for searching 400: 3648 N * log N = 3455
Costs for searching 299: 2638 N * log N = 2457
- Follow-Ups:
- RE: TREAPS
- From: Yoshiharu Kohayakawa <yoshi@ime.usp.br>