factor/extra/trees/splay/splay.factor

143 lines
3.5 KiB
Factor
Raw Normal View History

2009-03-04 17:02:21 -05:00
! Copyright (c) 2005 Mackenzie Straight.
! See http://factorcode.org/license.txt for BSD license.
2013-03-06 21:42:06 -05:00
USING: accessors assocs combinators kernel math.order parser
prettyprint.custom trees trees.private typed ;
2009-03-04 17:02:21 -05:00
IN: trees.splay
TUPLE: splay < tree ;
: <splay> ( -- tree )
\ splay new-tree ;
2010-05-04 19:10:34 -04:00
<PRIVATE
2013-03-06 21:42:06 -05:00
TYPED: rotate-right ( node: node -- node )
2009-03-04 17:02:21 -05:00
dup left>>
[ right>> swap left<< ] 2keep
[ right<< ] keep ;
2011-10-14 20:52:24 -04:00
2013-03-06 21:42:06 -05:00
TYPED: rotate-left ( node: node -- node )
2009-03-04 17:02:21 -05:00
dup right>>
[ left>> swap right<< ] 2keep
[ left<< ] keep ;
2009-03-04 17:02:21 -05:00
2013-03-06 21:42:06 -05:00
TYPED: link-right ( left right key node: node -- left right key node )
swap [ [ swap left<< ] 2keep
2009-03-04 17:02:21 -05:00
nip dup left>> ] dip swap ;
2013-03-06 21:42:06 -05:00
TYPED: link-left ( left right key node: node -- left right key node )
swap [ rot [ right<< ] 2keep
2009-03-04 17:02:21 -05:00
drop dup right>> swapd ] dip swap ;
2010-05-04 19:10:34 -04:00
: cmp ( key node -- obj node <=> )
2013-03-06 21:42:06 -05:00
2dup key>> <=> ; inline
2009-03-04 17:02:21 -05:00
2010-05-04 19:10:34 -04:00
: lcmp ( key node -- obj node <=> )
2013-03-06 21:42:06 -05:00
2dup left>> key>> <=> ; inline
2009-03-04 17:02:21 -05:00
2010-05-04 19:10:34 -04:00
: rcmp ( key node -- obj node <=> )
2013-03-06 21:42:06 -05:00
2dup right>> key>> <=> ; inline
2009-03-04 17:02:21 -05:00
DEFER: (splay)
2013-03-06 21:42:06 -05:00
TYPED: splay-left ( left right key node: node -- left right key node )
2009-03-04 17:02:21 -05:00
dup left>> [
2010-05-04 19:10:34 -04:00
lcmp +lt+ = [ rotate-right ] when
2009-03-04 17:02:21 -05:00
dup left>> [ link-right (splay) ] when
] when ;
2013-03-06 21:42:06 -05:00
TYPED: splay-right ( left right key node: node -- left right key node )
2009-03-04 17:02:21 -05:00
dup right>> [
2010-05-04 19:10:34 -04:00
rcmp +gt+ = [ rotate-left ] when
2009-03-04 17:02:21 -05:00
dup right>> [ link-left (splay) ] when
] when ;
2013-03-06 21:42:06 -05:00
TYPED: (splay) ( left right key node: node -- left right key node )
2010-05-04 19:10:34 -04:00
cmp {
{ +lt+ [ splay-left ] }
{ +gt+ [ splay-right ] }
{ +eq+ [ ] }
} case ;
2009-03-04 17:02:21 -05:00
2013-03-06 21:42:06 -05:00
TYPED: assemble ( head left right node: node -- root )
[ right>> swap left<< ] keep
[ left>> swap right<< ] keep
[ swap left>> swap right<< ] 2keep
[ swap right>> swap left<< ] keep ;
2009-03-04 17:02:21 -05:00
2013-03-06 21:42:06 -05:00
TYPED: splay-at ( key node: node -- node )
2009-03-04 17:02:21 -05:00
[ T{ node } clone dup dup ] 2dip
(splay) nip assemble ;
2013-03-06 21:42:06 -05:00
TYPED: do-splay ( key tree: splay -- )
[ root>> splay-at ] keep root<< ;
2009-03-04 17:02:21 -05:00
2013-03-06 21:42:06 -05:00
TYPED: splay-split ( key tree: splay -- node node )
2010-05-04 19:10:34 -04:00
2dup do-splay root>> cmp +lt+ = [
nip dup left>> swap f over left<<
2009-03-04 17:02:21 -05:00
] [
nip dup right>> swap f over right<< swap
2009-03-04 17:02:21 -05:00
] if ;
2013-03-06 21:42:06 -05:00
TYPED: get-splay ( key tree: splay -- node ? )
2010-05-04 19:10:34 -04:00
2dup do-splay root>> cmp +eq+ = [
2009-03-04 17:02:21 -05:00
nip t
] [
2drop f f
] if ;
: get-largest ( node -- node )
dup [ dup right>> [ nip get-largest ] when* ] when ;
: splay-largest ( node -- node )
dup [ dup get-largest key>> swap splay-at ] when ;
: splay-join ( n2 n1 -- node )
2011-10-14 20:52:24 -04:00
splay-largest [ [ right<< ] keep ] when* ;
2009-03-04 17:02:21 -05:00
2013-03-06 21:42:06 -05:00
TYPED: remove-splay ( key tree: splay -- )
2011-10-14 20:52:24 -04:00
2dup get-splay [
2009-03-04 17:02:21 -05:00
dup right>> swap left>> splay-join
2011-10-14 20:52:24 -04:00
>>root dec-count drop
] [ 3drop ] if ;
2009-03-04 17:02:21 -05:00
2013-03-06 21:42:06 -05:00
TYPED: set-splay ( value key tree: splay -- )
2dup get-splay [ 2nip value<< ] [
2009-03-04 17:02:21 -05:00
drop dup inc-count
2dup splay-split rot
[ [ swapd ] dip node boa ] dip root<<
2009-03-04 17:02:21 -05:00
] if ;
2013-03-06 21:42:06 -05:00
TYPED: new-root ( value key tree: splay -- )
2009-03-04 17:02:21 -05:00
1 >>count
[ swap <node> ] dip root<< ;
2009-03-04 17:02:21 -05:00
M: splay set-at ( value key tree -- )
dup root>> [ set-splay ] [ new-root ] if ;
M: splay at* ( key tree -- value ? )
dup root>> [
get-splay [ dup [ value>> ] when ] dip
] [
2drop f f
] if ;
M: splay delete-at ( key tree -- )
dup root>> [ remove-splay ] [ 2drop ] if ;
M: splay new-assoc
2drop <splay> ;
2010-05-04 19:10:34 -04:00
PRIVATE>
2009-03-04 17:02:21 -05:00
: >splay ( assoc -- tree )
T{ splay f f 0 } assoc-clone-like ;
SYNTAX: SPLAY{
\ } [ >splay ] parse-literal ;
2009-03-04 17:02:21 -05:00
M: splay assoc-like
drop dup splay? [ >splay ] unless ;
M: splay pprint-delims drop \ SPLAY{ \ } ;