factor/extra/trees/splay/splay.factor

141 lines
3.6 KiB
Factor
Raw Normal View History

2007-09-20 18:09:08 -04:00
! Copyright (c) 2005 Mackenzie Straight.
2008-01-17 17:55:59 -05:00
! See http://factorcode.org/license.txt for BSD license.
USING: arrays kernel math namespaces sequences assocs parser
2008-04-26 12:03:41 -04:00
prettyprint.backend trees generic math.order ;
2007-09-30 02:38:37 -04:00
IN: trees.splay
2007-09-20 18:09:08 -04:00
2008-05-05 02:54:56 -04:00
TUPLE: splay < tree ;
2007-12-25 02:28:55 -05:00
2008-03-11 22:01:39 -04:00
: <splay> ( -- tree )
2008-05-05 02:54:56 -04:00
\ splay new-tree ;
2007-12-25 02:28:55 -05:00
2007-09-20 18:09:08 -04:00
: rotate-right ( node -- node )
dup node-left
[ node-right swap set-node-left ] 2keep
[ set-node-right ] keep ;
2007-09-20 18:09:08 -04:00
: rotate-left ( node -- node )
dup node-right
[ node-left swap set-node-right ] 2keep
[ set-node-left ] keep ;
2007-09-20 18:09:08 -04:00
: link-right ( left right key node -- left right key node )
swap >r [ swap set-node-left ] 2keep
nip dup node-left r> swap ;
2007-09-20 18:09:08 -04:00
: link-left ( left right key node -- left right key node )
swap >r rot [ set-node-right ] 2keep
drop dup node-right swapd r> swap ;
2007-09-20 18:09:08 -04:00
: cmp ( key node -- obj node -1/0/1 )
2008-04-28 15:48:37 -04:00
2dup node-key key-side ;
2007-09-20 18:09:08 -04:00
: lcmp ( key node -- obj node -1/0/1 )
2008-04-28 15:48:37 -04:00
2dup node-left node-key key-side ;
2007-09-20 18:09:08 -04:00
: rcmp ( key node -- obj node -1/0/1 )
2008-04-28 15:48:37 -04:00
2dup node-right node-key key-side ;
2007-09-20 18:09:08 -04:00
DEFER: (splay)
: splay-left ( left right key node -- left right key node )
dup node-left [
2007-09-20 18:09:08 -04:00
lcmp 0 < [ rotate-right ] when
dup node-left [ link-right (splay) ] when
2007-09-20 18:09:08 -04:00
] when ;
: splay-right ( left right key node -- left right key node )
dup node-right [
2007-09-20 18:09:08 -04:00
rcmp 0 > [ rotate-left ] when
dup node-right [ link-left (splay) ] when
2007-09-20 18:09:08 -04:00
] when ;
: (splay) ( left right key node -- left right key node )
cmp dup 0 <
[ drop splay-left ] [ 0 > [ splay-right ] when ] if ;
: assemble ( head left right node -- root )
[ node-right swap set-node-left ] keep
[ node-left swap set-node-right ] keep
[ swap node-left swap set-node-right ] 2keep
[ swap node-right swap set-node-left ] keep ;
2007-09-20 18:09:08 -04:00
: splay-at ( key node -- node )
>r >r T{ node } clone dup dup r> r>
2007-09-20 18:09:08 -04:00
(splay) nip assemble ;
: splay ( key tree -- )
[ tree-root splay-at ] keep set-tree-root ;
2007-09-20 18:09:08 -04:00
: splay-split ( key tree -- node node )
2dup splay tree-root cmp 0 < [
nip dup node-left swap f over set-node-left
2007-09-20 18:09:08 -04:00
] [
nip dup node-right swap f over set-node-right swap
2007-09-20 18:09:08 -04:00
] if ;
2007-12-25 02:28:55 -05:00
: get-splay ( key tree -- node ? )
2dup splay tree-root cmp 0 = [
2007-09-20 18:09:08 -04:00
nip t
] [
2drop f f
] if ;
: get-largest ( node -- node )
dup [ dup node-right [ nip get-largest ] when* ] when ;
2007-09-20 18:09:08 -04:00
: splay-largest ( node -- node )
dup [ dup get-largest node-key swap splay-at ] when ;
2007-09-20 18:09:08 -04:00
: splay-join ( n2 n1 -- node )
splay-largest [
[ set-node-right ] keep
2007-09-20 18:09:08 -04:00
] [
drop f
] if* ;
2007-12-25 02:28:55 -05:00
: remove-splay ( key tree -- )
tuck get-splay nip [
dup dec-count
dup node-right swap node-left splay-join
swap set-tree-root
2007-09-20 18:09:08 -04:00
] [ drop ] if* ;
2007-12-25 02:28:55 -05:00
: set-splay ( value key tree -- )
2dup get-splay [ 2nip set-node-value ] [
drop dup inc-count
2007-09-20 18:09:08 -04:00
2dup splay-split rot
>r >r swapd r> node boa r> set-tree-root
2007-09-20 18:09:08 -04:00
] if ;
: new-root ( value key tree -- )
[ 1 swap set-tree-count ] keep
2007-12-25 02:28:55 -05:00
>r swap <node> r> set-tree-root ;
M: splay set-at ( value key tree -- )
2007-12-25 02:28:55 -05:00
dup tree-root [ set-splay ] [ new-root ] if ;
M: splay at* ( key tree -- value ? )
dup tree-root [
2007-12-25 02:28:55 -05:00
get-splay >r dup [ node-value ] when r>
2007-09-20 18:09:08 -04:00
] [
2drop f f
] if ;
M: splay delete-at ( key tree -- )
2007-12-25 02:28:55 -05:00
dup tree-root [ remove-splay ] [ 2drop ] if ;
2007-09-20 18:09:08 -04:00
M: splay new-assoc
2drop <splay> ;
2007-09-20 18:09:08 -04:00
2008-03-11 22:01:39 -04:00
: >splay ( assoc -- tree )
2008-05-05 02:54:56 -04:00
T{ splay f f 0 } assoc-clone-like ;
2007-09-20 18:09:08 -04:00
: SPLAY{
\ } [ >splay ] parse-literal ; parsing
2007-09-20 18:09:08 -04:00
M: splay assoc-like
2008-01-17 17:55:59 -05:00
drop dup splay? [ >splay ] unless ;
2007-09-20 18:09:08 -04:00
M: splay pprint-delims drop \ SPLAY{ \ } ;