* AVL and red-black trees
@ 2001-04-17 12:14 Roberto
2001-04-18 1:53 ` Marc A. Criley
2001-04-18 19:04 ` Simon Wright
0 siblings, 2 replies; 5+ messages in thread
From: Roberto @ 2001-04-17 12:14 UTC (permalink / raw)
Hi, i'm new in this group and I need an implementation of AVL trees and
red-black trees to make a comparation.
--
Thanks in advance.
Roberto
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: AVL and red-black trees
2001-04-17 12:14 AVL and red-black trees Roberto
@ 2001-04-18 1:53 ` Marc A. Criley
[not found] ` <9bjhl4$n6t$1@news.huji.ac.il>
2001-04-18 19:04 ` Simon Wright
1 sibling, 1 reply; 5+ messages in thread
From: Marc A. Criley @ 2001-04-18 1:53 UTC (permalink / raw)
Roberto wrote:
>
> Hi, i'm new in this group and I need an implementation of AVL trees and
> red-black trees to make a comparation.
>
Compare the implementations how? The concepts of each are language
independent and layed out in any decent data structures textbook.
Marc A. Criley
Senior Staff Engineer
Quadrus Corporation
www.quadruscorp.com
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: AVL and red-black trees
[not found] ` <9bjhl4$n6t$1@news.huji.ac.il>
@ 2001-04-18 13:41 ` Roberto
2001-04-19 2:53 ` Frank Ranner
0 siblings, 1 reply; 5+ messages in thread
From: Roberto @ 2001-04-18 13:41 UTC (permalink / raw)
I must search 2 implementations (better in Ada to not translate) and make a
lot of tests (insert, delete and search) with them.
The problem is that I haven't found an implementation with the remove
operation (and the explanations that I've found in Internet aren't clear).
--
Greetings
Roberto
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: AVL and red-black trees
2001-04-17 12:14 AVL and red-black trees Roberto
2001-04-18 1:53 ` Marc A. Criley
@ 2001-04-18 19:04 ` Simon Wright
1 sibling, 0 replies; 5+ messages in thread
From: Simon Wright @ 2001-04-18 19:04 UTC (permalink / raw)
"Roberto" <rcasas@able.es> writes:
> Hi, i'm new in this group and I need an implementation of AVL trees
> and red-black trees to make a comparation.
The Boock Components at http://www.pushface.org/components/bc/ have an
AVL tree implementation.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: AVL and red-black trees
2001-04-18 13:41 ` Roberto
@ 2001-04-19 2:53 ` Frank Ranner
0 siblings, 0 replies; 5+ messages in thread
From: Frank Ranner @ 2001-04-19 2:53 UTC (permalink / raw)
Roberto wrote:
>
> I must search 2 implementations (better in Ada to not translate) and make a
> lot of tests (insert, delete and search) with them.
>
> The problem is that I haven't found an implementation with the remove
> operation (and the explanations that I've found in Internet aren't clear).
>
> --
>
> Greetings
>
> Roberto
Here are the sample implementations that were provided by my uni. you
will need to
split them up and get them working.
AVL
==============================
with text_io; use text_io;
procedure avl is
type balance is (left_heavy, balanced, right_heavy);
type node;
type ptr_to_node is access node;
type node is record
data : integer;
count : positive := 1;
left, right : ptr_to_node := null;
bal : balance := balanced;
end record;
root : ptr_to_node := null;
hh : boolean := false;
procedure print (p : ptr_to_node; n : integer) is
i : integer;
begin
if p /= null then
print (p.right, n+4);
for i in 1 .. n loop
put(' ');
end loop;
put(integer'image(p.data));
new_line;
print (p.left, n+4);
end if;
end print;
procedure insert (x : integer; p : in out ptr_to_node; h : in out
boolean) is
p1, p2 : ptr_to_node;
begin
if p = null then
-- word is not in tree : insert it
p := new node;
p.data := x;
h := true;
elsif x < p.data then
insert (x, p.left, h);
if h then
case p.bal is
when right_heavy => p.bal := balanced;
h := false;
when balanced => p.bal := left_heavy;
when left_heavy => p1 := p.left;
if p1.bal = left_heavy then
-- single LL rotation
p.left := p1.right;
p1.right := p;
p.bal := balanced;
p := p1;
else
-- double LR rotation
p2 := p1.right;
p1.right := p2.left;
p2.left := p1;
p.left := p2.right;
p2.right := p;
if p2.bal = left_heavy then
p.bal := right_heavy;
else
p.bal := balanced;
end if;
if p2.bal = right_heavy then
p1.bal := left_heavy;
else
p1.bal := balanced;
end if;
end if;
p.bal := balanced;
h := false;
end case;
end if;
elsif x > p.data then
insert (x, p.right, h);
if h then
case p.bal is
when left_heavy => p.bal := balanced;
h := false;
when balanced => p.bal := right_heavy;
when right_heavy => -- rebalance
p1 := p.right;
if p.bal = right_heavy then
-- single RR rotation
p.right := p1.left;
p1.left := p;
p.bal := balanced;
p := p1;
else
-- double RL rotation
p2 := p1.left;
p1.left := p2.right;
p2.right := p1;
p.right := p2.left;
p2.left := p;
if p2.bal = right_heavy then
p.bal := left_heavy;
else
p.bal := balanced;
end if;
if p2.bal = left_heavy then
p1.bal := right_heavy;
else
p1.bal := balanced;
end if;
end if;
p.bal := balanced;
h := false;
end case;
end if;
else
p.count := p.count + 1;
h := false;
end if;
end;
procedure delete (x : integer; p : in out ptr_to_node; h : in out
boolean) is
q : ptr_to_node;
procedure balance_1 (p : in out ptr_to_node; h : in out boolean) is
p1, p2 : ptr_to_node;
b1, b2 : balance;
begin
-- h = true, left branch has become less high
case p.bal is
when left_heavy => p.bal := balanced;
when balanced => p.bal := right_heavy;
h := false;
when right_heavy => -- rebalance
p1 := p.right;
b1 := p1.bal;
if b1 >= balanced then
-- single RR rotation
p.right := p1.left;
p1.left := p;
if b1 = balanced then
p.bal := right_heavy;
p1.bal := left_heavy;
h := false;
else
p.bal := balanced;
p1.bal := balanced;
end if;
p := p1;
else
-- double RL rotation
p2 := p1.left;
b2 := p2.bal;
p1.left := p2.right;
p2.right := p1;
p.right := p2.left;
p2.left := p;
if b2 = right_heavy then
p.bal := left_heavy;
else
p.bal := balanced;
end if;
if b2 = left_heavy then
p1.bal := right_heavy;
else
p1.bal := balanced;
end if;
p := p2;
p2.bal := balanced;
end if;
end case;
end;
procedure balance_2 (p : in out ptr_to_node; h : in out boolean) is
p1, p2 : ptr_to_node;
b1, b2 : balance;
begin
case p.bal is
when right_heavy => p.bal := balanced;
when balanced => p.bal := left_heavy;
h := false;
when left_heavy => -- rebalance
p1 := p.left;
b1 := p1.bal;
if b1 <= balanced then
-- single LL rotation
p.left := p1.right;
p1.right := p;
if b1 = balanced then
p.bal := left_heavy;
p1.bal := right_heavy;
h := false;
else
p.bal := balanced;
p1.bal := balanced;
end if;
p := p1;
else
-- double LR rotation
p2 := p1.right;
b2 := p2.bal;
p1.right := p2.left;
p2.left := p1;
p.left := p2.right;
p2.right := p;
if b2 = left_heavy then
p.bal := right_heavy;
else
p.bal := balanced;
end if;
if b2 = right_heavy then
p1.bal := left_heavy;
else
p1.bal := balanced;
end if;
p := p2;
p2.bal := balanced;
end if;
end case;
end balance_2;
procedure del (r : in out ptr_to_node; h : in out boolean) is
begin
-- h = false
if r.right /= null then
del (r.right, h);
if h then
balance_2(r, h);
end if;
else
q.data := r.data;
q.count := r.count;
r := r.left;
h := true;
end if;
end;
begin -- delete
if p = null then
--put_line("data is not in tree");
h := false;
elsif x < p.data then
delete (x, p.left, h);
if h then
balance_1 (p, h);
end if;
elsif x > p.data then
delete (x, p.right, h);
if h then
balance_2 (p, h);
end if;
else
-- delete p
q := p;
if q.right = null then
p := q.left;
h := true;
elsif q.left = null then
p := q.right;
h := true;
else
del (q.left, h);
if h then
balance_1 (p, h);
end if;
end if;
-- dispose(q);
end if;
end delete;
begin
for i in 1 .. 31 loop
insert (i, root, hh);
end loop;
print(root, 1);
for i in 10 .. 20 loop
delete (i, root, hh);
end loop;
print(root, 1);
end;
=================================
Red-black
=================================
with tree_dec; use tree_dec;
with ansi; use ansi;
package rb_tree is
x:integer:=0;
procedure Initialize (t: in out tree);
procedure insert (x: tree; e: item);
procedure delete (t: in out tree; e: item; successful: out
boolean);
function locate (t: tree; e: item) return tree;
procedure printin (t: tree; indent:natural:=1);
function nodes (t: tree) return natural;
-- function leaves (t: tree) return natural;
-- function not_leaves (t: tree) return natural;
-- function height (t: tree) return natural;
function Empty (t: tree) return boolean;
end rb_tree;
with text_io;
package body rb_tree is
z:tree;
head:tree;
toggle:boolean;
package item_io is new text_io.integer_io(item); use item_io;
procedure Initialize (t: in out tree) is
begin
z:=new node;
z.red:=false;
head:=new node;
head.data:=item'first;
head.right:=z;
head.left:=z;
head.red:=false;
z.data:=item'last;
t:=head;
end initialize;
procedure insert (x: tree; e: item) is
xx:tree:=x;
gg,g,f,temp:tree;
function split(v:item; gg,g,f,x:tree) return tree is
tgg:tree:=gg;
tg:tree:=g;
tf:tree:=f;
tx:tree:=x;
function rotate(v:item;y:tree) return tree is
s,gs:tree;
begin
if v<y.data then
s:=y.left;
else
s:=y.right;
end if;
if v<s.data then
gs:=s.left;
s.left:=gs.right;
gs.right:=s;
else
gs:=s.right;
s.right:=gs.left;
gs.left:=s;
end if;
if v<y.data then
y.left:=gs;
else
y.right:=gs;
end if;
return (gs);
end rotate;
begin
tx.red:=true;
tx.left.red:=false;
tx.right.red:=false;
if tf.red then
tg.red:=true;
if (v<tg.data)/=(v<tf.data) then
tf:=rotate(v,tg);
end if;
tx:=rotate(v,tgg);
tx.red:=false;
end if;
head.right.red:=false; -- set head to red.
return tx;
end split;
begin
f:=xx;
g:=xx;
loop
gg:=g;
g:=f;
f:=xx;
if e<xx.data then
xx:=xx.left;
else
xx:=xx.right;
end if;
exit when xx=z;
if xx.left.red and xx.right.red then
xx:=split(e,gg,g,f,xx);
end if;
end loop;
xx:=new node;
xx.data:=e;
xx.left:=z;
xx.right:=z;
if e<f.data then
f.left:=xx;
else
f.right:=xx;
end if;
temp:=xx;
xx:=split(e,gg,g,f,xx);
-- z.red:=true;
-- return temp;
end insert;
procedure printin(t:tree; indent: natural:=1) is
cost,i:natural:=indent;
begin
if (t/=z) then
if t.red then
cost:=cost-1;
end if;
printin(t.left,cost+1);
for i in 1..cost*item'width loop
put(" ");
end loop;
if (t.left.red)and(t.right.red) then
text(foreground=>lightblue);
elsif (t.left.red)or(t.right.red) then
text(foreground=>lightgreen);
elsif t.red then
text(foreground=>lightred);
else
text(foreground=>white);
end if;
put(t.data);
new_line;
x:=x+1;
printin(t.right,cost+1);
end if;
end printin;
procedure delete (t: in out tree; e: item; successful: out boolean)
is
q:tree;
procedure crossoutl(r: in out tree) is
begin
if r.left/=z then
crossoutl(r.left);
else
q.data:=r.data;
q:=r;
r:=r.right;
end if;
end crossoutl;
procedure crossoutr(r: in out tree) is
begin
if r.right/=z then
crossoutr(r.right);
else
q.data:=r.data;
q:=r;
r:=r.left;
end if;
end crossoutr;
begin
successful:=true;
if t=z then
successful:=false;
elsif e<t.data then
delete(t.left,e,successful);
elsif e>t.data then
delete(t.right,e,successful);
else
q:=t;
if q.right=z then
t:=q.left;
elsif q.left=z then
t:=q.right;
else
if q.right.red=q.left.red then
if toggle then
crossoutl(q.right);
toggle:=false;
else
crossoutr(q.left);
toggle:=true;
end if;
elsif q.left.red then
crossoutr(q.left);
elsif q.right.red then
crossoutl(q.right);
end if;
end if;
end if;
end delete;
function nodes(t:tree) return natural is
begin
if t=z then
return 0;
else
return 1+nodes(t.left)+nodes(t.right);
end if;
end nodes;
function locate (t: tree; e: item) return tree is
found:boolean:=false;
p:tree:=t;
begin
while (p/=null) and (not found) loop
if p.data=e then
found:=true;
elsif e<t.data then
p:=p.left;
else
p:=p.right;
end if;
end loop;
return p;
end locate;
function not_leaves(t:tree) return natural is
begin
if empty(t) then
return 0;
elsif (t.left=null)and(t.right=null) then
return 0;
else
return 1+not_leaves(t.left)+not_leaves(t.right);
end if;
end not_leaves;
function leaves(t:tree) return natural is
begin
if empty(t) then
return 0;
elsif (t.left=null)and(t.right=null) then
return 1;
-- else
-- return leaves(t.left)+nodes(t.right);
end if;
end leaves;
function height(t:tree) return natural is
function max(a,b:natural) return natural is
begin
if a>b then
return a;
else
return b;
end if;
end max;
begin
if empty(t) then
return 0;
elsif (t.left=null)and(t.right=null) then
return 1;
else
return 1+max(height(t.left),height(t.right));
end if;
end height;
function Empty (t: tree) return boolean is
begin
return t=null;
end;
end rb_tree;
===============================
treedec
===============================
package Tree_Dec is -- declarations for any list, queue or stack.
type item is new integer;
type node;
type tree is access node;
type node is
record
data : item:=item'first;
left : tree:=null;
right: tree:=null;
red : boolean:=false; -- this is for bed/black trees only,
binary
-- trees will just ignore it.
end record;
procedure put_item(e:item);
procedure get_item(e:out item);
end Tree_Dec;
with text_io;
package body Tree_Dec is
procedure put_item(e:item) is -- a procedure to write an element to
the
-- screen.
begin
text_io.put(item'image(e));
text_io.new_line;
end put_item;
procedure get_item(e:out item) is -- a procedure to read an element
from
-- the keyboard.
temp:string(1..80):=(others=>' ');
len:integer;
begin
text_io.get_line(temp,len);
e:=item(integer'value(temp(1..len)));
end get_item;
end Tree_Dec;
========================
A crappy ansi package
========================
with text_io; use text_io;
package ansi is
-- parameter if no change takes place.
no_change : constant natural:=natural'last;
-- Attributes for procedure text.
reset : constant natural:=0;
underscore : constant natural:=1;
blink : constant natural:=2;
inverse : constant natural:=4;
concealed : constant natural:=8;
-- Colours for procedure text.
-- (the colours are foreground colours,
-- 10 is added by the procedure
-- for background colours and
-- 1xx is the bold version of xx)
black : constant natural:=30;
darkgrey : constant natural:=130;
darkred : constant natural:=31;
lightred : constant natural:=131;
darkgreen : constant natural:=32;
lightgreen : constant natural:=132;
brown : constant natural:=33;
yellow : constant natural:=133;
darkblue : constant natural:=34;
lightblue : constant natural:=134;
darkmagenta : constant natural:=35;
lightmagenta : constant natural:=135;
darkcyan : constant natural:=36;
lightcyan : constant natural:=136;
lightgrey : constant natural:=37;
white : constant natural:=137;
type screen is
record
attrib:natural:=reset;
back_col:natural:=black;
fore_col:natural:=lightgrey;
end record;
procedure put(c:character) renames text_io.put; -- so you don't have
to
procedure put(s:string) renames text_io.put; -- always with/use
text_io.
procedure put_line(s:string) renames text_io.put_line;
procedure new_line(spacing:positive_count:=1) renames
text_io.new_line;
procedure home;
procedure clrscr;
procedure clreol;
procedure gotoxy(x,y:natural:=0);
procedure cursor_left(x:natural);
procedure cursor_right(x:natural);
procedure cursor_up(y:natural);
procedure cursor_down(y:natural);
procedure relxy(x,y:integer:=0);
procedure text(attribute:natural:=no_change;
foreground:natural:=no_change;
background:natural:=no_change);
procedure beep;
end ansi;
package body ansi is
esc : constant string:=(ascii.esc,'[');
-- esc : constant string:=("esc["); -- for testing purposes.
mem : screen;
procedure home is
begin
put(esc & ";H");
end home;
procedure clrscr is
begin
put(esc & "2J");
end clrscr;
procedure clreol is
begin
put(esc & 'K');
end clreol;
function convert(x:natural) return string is
-- a proc to convert from natural to string without leading blank.
s:string(1..natural'image(x)'length):=natural'image(x);
begin
return s(2..s'last);
end convert;
procedure gotoxy (x,y:natural:=0) is
begin
put(esc & convert(y) & ';' & convert(x) & 'H');
end gotoxy;
procedure cursor_left(x:natural) is
begin
put(esc & convert(x) & 'D');
end cursor_left;
procedure cursor_right(x:natural) is
begin
put(esc & convert(x) & 'C');
end cursor_right;
procedure cursor_up(y:natural) is
begin
put(esc & convert(y) & 'A');
end cursor_up;
procedure cursor_down(y:natural) is
begin
put(esc & convert(y) & 'B');
end cursor_down;
procedure relxy (x,y:integer:=0) is
begin
if x<0 then
cursor_left(-x);
elsif x>0 then
cursor_right(x);
end if;
if y<0 then
cursor_up(-y);
elsif y>0 then
cursor_down(y);
end if;
end relxy;
procedure text(attribute:natural:=no_change;
foreground:natural:=no_change;
background:natural:=no_change) is
i:natural:=8;
begin
if foreground/=no_change then
mem.attrib:=attribute;
end if;
if mem.attrib=reset then
mem.attrib:=no_change;
put(esc&"0m");
end if;
if foreground/=no_change then
mem.fore_col:=foreground;
end if;
if background/=no_change then
mem.back_col:=background;
end if;
put(esc&"0m"); -- reset for starters.
if mem.fore_col>100 then
put(esc&"1;"&convert(mem.fore_col-100)&"m");
else
put(esc&convert(mem.fore_col)&"m");
end if;
put(esc&"0m");
if mem.back_col>100 then
put(esc&convert(mem.back_col-90)&"m");
else
put(esc&convert(mem.back_col+10)&"m");
end if;
put(esc&"0m");
while i>0 loop
if mem.attrib>=i then
if i=concealed then put(esc&"8m"); end if;
if i=inverse then put(esc&"7m"); end if;
if i=blink then put(esc&"5m"); end if;
if i=underscore then put(esc&"4m"); end if;
-- bold is not required due to colouring.
mem.attrib:=mem.attrib-i;
end if;
i:=i/2;
end loop;
end;
procedure beep is
begin
put(ascii.bel);
end beep;
end ansi;
=====================
Hope this helps.
regards, Frank Ranner
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2001-04-19 2:53 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-04-17 12:14 AVL and red-black trees Roberto
2001-04-18 1:53 ` Marc A. Criley
[not found] ` <9bjhl4$n6t$1@news.huji.ac.il>
2001-04-18 13:41 ` Roberto
2001-04-19 2:53 ` Frank Ranner
2001-04-18 19:04 ` Simon Wright
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox