Splay tree fixes

db4
Daniel Ehrenberg 2007-12-25 02:28:55 -05:00
parent 18f85fbaf3
commit d5baea215d
3 changed files with 36 additions and 18 deletions

View File

@ -8,7 +8,7 @@ IN: temporary
100 [ drop 100 random swap at drop ] curry* each ; 100 [ drop 100 random swap at drop ] curry* each ;
: make-numeric-splay-tree ( n -- splay-tree ) : make-numeric-splay-tree ( n -- splay-tree )
dup <splay-tree> -rot [ pick set-at ] 2each ; <splay> [ [ dupd set-at ] curry each ] keep ;
[ t ] [ [ t ] [
100 make-numeric-splay-tree dup randomize-numeric-splay-tree 100 make-numeric-splay-tree dup randomize-numeric-splay-tree
@ -18,10 +18,10 @@ IN: temporary
[ 10 ] [ 10 make-numeric-splay-tree keys length ] unit-test [ 10 ] [ 10 make-numeric-splay-tree keys length ] unit-test
[ 10 ] [ 10 make-numeric-splay-tree values length ] unit-test [ 10 ] [ 10 make-numeric-splay-tree values length ] unit-test
[ f ] [ <splay-tree> f 4 pick set-at 4 swap at ] unit-test [ f ] [ <splay> f 4 pick set-at 4 swap at ] unit-test
! Ensure that f can be a value ! Ensure that f can be a value
[ t ] [ <splay-tree> f 4 pick set-at 4 swap key? ] unit-test [ t ] [ <splay> f 4 pick set-at 4 swap key? ] unit-test
[ [
{ { 1 "a" } { 2 "b" } { 3 "c" } { 4 "d" } { 5 "e" } { 6 "f" } } { { 1 "a" } { 2 "b" } { 3 "c" } { 4 "d" } { 5 "e" } { 6 "f" } }
@ -29,5 +29,5 @@ IN: temporary
{ {
{ 4 "d" } { 5 "e" } { 6 "f" } { 4 "d" } { 5 "e" } { 6 "f" }
{ 1 "a" } { 2 "b" } { 3 "c" } { 1 "a" } { 2 "b" } { 3 "c" }
} >splay-tree >alist } >splay >alist
] unit-test ] unit-test

View File

@ -5,10 +5,13 @@ prettyprint.backend trees generic ;
IN: trees.splay IN: trees.splay
TUPLE: splay ; TUPLE: splay ;
: <splay> ( -- splay-tree ) : <splay> ( -- splay-tree )
splay construct-empty \ splay construct-empty
<tree> over set-delegate ; <tree> over set-delegate ;
INSTANCE: splay assoc
: rotate-right ( node -- node ) : rotate-right ( node -- node )
dup node-left dup node-left
[ node-right swap set-node-left ] 2keep [ node-right swap set-node-left ] 2keep
@ -74,7 +77,7 @@ DEFER: (splay)
nip dup node-right swap f over set-node-right swap nip dup node-right swap f over set-node-right swap
] if ; ] if ;
: (get-splay) ( key tree -- node ? ) : get-splay ( key tree -- node ? )
2dup splay tree-root cmp 0 = [ 2dup splay tree-root cmp 0 = [
nip t nip t
] [ ] [
@ -94,36 +97,36 @@ DEFER: (splay)
drop f drop f
] if* ; ] if* ;
: (remove-splay) ( key tree -- ) : remove-splay ( key tree -- )
tuck (get-splay) nip [ tuck get-splay nip [
dup tree-count 1- over set-tree-count dup dec-count
dup node-right swap node-left splay-join dup node-right swap node-left splay-join
swap set-tree-root swap set-tree-root
] [ drop ] if* ; ] [ drop ] if* ;
: (set-splay) ( value key tree -- ) : set-splay ( value key tree -- )
2dup (get-splay) [ 2nip set-node-value ] [ 2dup get-splay [ 2nip set-node-value ] [
drop dup tree-count 1+ over set-tree-count drop dup inc-count
2dup splay-split rot 2dup splay-split rot
>r node construct-boa r> set-tree-root >r >r swapd r> node construct-boa r> set-tree-root
] if ; ] if ;
: new-root ( value key tree -- ) : new-root ( value key tree -- )
[ 1 swap set-tree-count ] keep [ 1 swap set-tree-count ] keep
>r <node> r> set-tree-root ; >r swap <node> r> set-tree-root ;
M: splay set-at ( value key tree -- ) M: splay set-at ( value key tree -- )
dup tree-root [ (set-splay) ] [ new-root ] if ; dup tree-root [ set-splay ] [ new-root ] if ;
M: splay at* ( key tree -- value ? ) M: splay at* ( key tree -- value ? )
dup tree-root [ dup tree-root [
(get-splay) >r dup [ node-value ] when r> get-splay >r dup [ node-value ] when r>
] [ ] [
2drop f f 2drop f f
] if ; ] if ;
M: splay delete-at ( key tree -- ) M: splay delete-at ( key tree -- )
dup tree-root [ (remove-splay) ] [ 2drop ] if ; dup tree-root [ remove-splay ] [ 2drop ] if ;
M: splay new-assoc M: splay new-assoc
2drop <splay> ; 2drop <splay> ;
@ -140,3 +143,10 @@ M: splay assoc-like
] unless ; ] unless ;
M: splay pprint-delims drop \ SPLAY{ \ } ; M: splay pprint-delims drop \ SPLAY{ \ } ;
M: splay >pprint-sequence >alist ;
M: splay pprint-narrow? drop t ;
! When tuple inheritance is used, the following lines won't be necessary
M: splay assoc-size tree-count ;
M: splay clear-assoc delegate clear-assoc ;
M: splay assoc-find >r tree-root r> find-node ;

View File

@ -8,6 +8,8 @@ TUPLE: tree root count ;
: <tree> ( -- tree ) : <tree> ( -- tree )
f 0 tree construct-boa ; f 0 tree construct-boa ;
INSTANCE: tree assoc
TUPLE: node key value left right ; TUPLE: node key value left right ;
: <node> ( key value -- node ) : <node> ( key value -- node )
f f node construct-boa ; f f node construct-boa ;
@ -19,6 +21,12 @@ SYMBOL: current-side
: go-left? ( -- ? ) current-side get left = ; : go-left? ( -- ? ) current-side get left = ;
: inc-count ( tree -- )
dup tree-count 1+ swap set-tree-count ;
: dec-count ( tree -- )
dup tree-count 1- swap set-tree-count ;
: node-link@ ( node ? -- node ) : node-link@ ( node ? -- node )
go-left? xor [ node-left ] [ node-right ] if ; go-left? xor [ node-left ] [ node-right ] if ;
: set-node-link@ ( left parent ? -- ) : set-node-link@ ( left parent ? -- )
@ -60,7 +68,7 @@ SYMBOL: current-side
] [ ] [
choose-branch node-at* choose-branch node-at*
] if ] if
] [ f f ] if* ; ] [ drop f f ] if* ;
M: tree at* ( key tree -- value ? ) M: tree at* ( key tree -- value ? )
tree-root node-at* ; tree-root node-at* ;