trees.avl: fix it (broken since 2010)
rotate creates cycles in the tree and drops nodes...
This either breaks everything (infinite recursion) or silently
loses data.
Improve the tests to ensure rotate does what it's supposed to do.
This is a partial revert from 15226d8
char-rename
parent
eb46e23eab
commit
3d60f7ad5a
|
@ -2,31 +2,35 @@ USING: kernel tools.test trees trees.avl math random sequences
|
||||||
assocs accessors trees.avl.private trees.private ;
|
assocs accessors trees.avl.private trees.private ;
|
||||||
IN: trees.avl.tests
|
IN: trees.avl.tests
|
||||||
|
|
||||||
{ "key1" 0 "key2" 0 } [
|
{ "key1" 0 "key3" "key2" 0 } [
|
||||||
T{ avl-node f "key1" f f T{ avl-node f "key2" f f f 1 } 2 }
|
T{ avl-node f "key1" f f T{ avl-node f "key2" f T{ avl-node f "key3" } f 1 } 2 }
|
||||||
[ single-rotate ] go-left
|
[ single-rotate ] go-left
|
||||||
[ left>> dup key>> swap balance>> ] keep
|
[ left>> dup key>> swap balance>> ] keep
|
||||||
|
[ left>> right>> key>> ] keep
|
||||||
dup key>> swap balance>>
|
dup key>> swap balance>>
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
{ "key1" 0 "key2" 0 } [
|
{ "key1" 0 "key3" "key2" 0 } [
|
||||||
T{ avl-node f "key1" f f T{ avl-node f "key2" f f f 1 } 2 }
|
T{ avl-node f "key1" f f T{ avl-node f "key2" f T{ avl-node f "key3" } f 1 } 2 }
|
||||||
[ select-rotate ] go-left
|
[ select-rotate ] go-left
|
||||||
[ left>> dup key>> swap balance>> ] keep
|
[ left>> dup key>> swap balance>> ] keep
|
||||||
|
[ left>> right>> key>> ] keep
|
||||||
dup key>> swap balance>>
|
dup key>> swap balance>>
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
{ "key1" 0 "key2" 0 } [
|
{ "key1" 0 "key3" "key2" 0 } [
|
||||||
T{ avl-node f "key1" f T{ avl-node f "key2" f f f -1 } f -2 }
|
T{ avl-node f "key1" f T{ avl-node f "key2" f f T{ avl-node f "key3" } -1 } f -2 }
|
||||||
[ single-rotate ] go-right
|
[ single-rotate ] go-right
|
||||||
[ right>> dup key>> swap balance>> ] keep
|
[ right>> dup key>> swap balance>> ] keep
|
||||||
|
[ right>> left>> key>> ] keep
|
||||||
dup key>> swap balance>>
|
dup key>> swap balance>>
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
{ "key1" 0 "key2" 0 } [
|
{ "key1" 0 "key3" "key2" 0 } [
|
||||||
T{ avl-node f "key1" f T{ avl-node f "key2" f f f -1 } f -2 }
|
T{ avl-node f "key1" f T{ avl-node f "key2" f f T{ avl-node f "key3" } -1 } f -2 }
|
||||||
[ select-rotate ] go-right
|
[ select-rotate ] go-right
|
||||||
[ right>> dup key>> swap balance>> ] keep
|
[ right>> dup key>> swap balance>> ] keep
|
||||||
|
[ right>> left>> key>> ] keep
|
||||||
dup key>> swap balance>>
|
dup key>> swap balance>>
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,9 @@ TUPLE: avl-node < node balance ;
|
||||||
'[ _ + ] change-balance ;
|
'[ _ + ] change-balance ;
|
||||||
|
|
||||||
: rotate ( node -- node )
|
: rotate ( node -- node )
|
||||||
dup
|
dup node+link
|
||||||
[ node+link ]
|
dup node-link
|
||||||
[ node-link ]
|
pick set-node+link
|
||||||
[ set-node+link ] tri
|
|
||||||
[ set-node-link ] keep ;
|
[ set-node-link ] keep ;
|
||||||
|
|
||||||
: single-rotate ( node -- node )
|
: single-rotate ( node -- node )
|
||||||
|
|
Loading…
Reference in New Issue