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
Jon Harper 2016-11-27 14:49:35 +01:00 committed by John Benediktsson
parent eb46e23eab
commit 3d60f7ad5a
2 changed files with 15 additions and 12 deletions

View File

@ -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

View File

@ -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 )