Make it into a stable sort

db4
Slava Pestov 2008-07-15 23:37:09 -05:00
parent 6577d4e500
commit 90b68c062d
3 changed files with 14 additions and 4 deletions

View File

@ -3,6 +3,10 @@ sequences math.order ;
IN: sorting
ARTICLE: "sequences-sorting" "Sorting sequences"
"The " { $vocab-link "sorting" } " vocabulary implements the merge-sort algorithm. It runs in " { $snippet "O(n log n)" } " time, and is a " { $emphasis "stable" } " sort, meaning that the order of equal elements is preserved."
$nl
"The algorithm only allocates two additional arrays, both the size of the input sequence, and uses iteration rather than recursion, and thus is suitable for sorting large sequences."
$nl
"Sorting combinators all take comparator quotations with stack effect " { $snippet "( elt1 elt2 -- <=> )" } ", where the output value is one of the three " { $link "order-specifiers" } "."
$nl
"Sorting a sequence with a custom comparator:"

View File

@ -18,3 +18,9 @@ unit-test
] unit-test
[ ] [ { 1 2 } [ 2drop 1 ] sort drop ] unit-test
! Is it a stable sort?
[ t ] [ { { 1 "a" } { 1 "b" } { 1 "c" } } dup sort-keys = ] unit-test
[ { { 1 "a" } { 1 "b" } { 1 "c" } { 1 "e" } { 2 "d" } } ]
[ { { 1 "a" } { 1 "b" } { 1 "c" } { 2 "d" } { 1 "e" } } sort-keys ] unit-test

View File

@ -50,13 +50,13 @@ TUPLE: merge
: dump-r [ [ from2>> ] [ to2>> ] [ seq>> ] tri ] [ accum>> ] bi dump ; inline
: l-next [ [ l-elt ] [ [ 1+ ] change-from1 drop ] bi ] [ accum>> ] bi push ; inline
: r-next [ [ r-elt ] [ [ 1+ ] change-from2 drop ] bi ] [ accum>> ] bi push ; inline
: decide [ [ l-elt ] [ r-elt ] bi ] dip call +lt+ eq? ; inline
: decide [ [ l-elt ] [ r-elt ] bi ] dip call +gt+ eq? ; inline
: (merge) ( merge quot -- )
over l-done? [ drop dump-r ] [
over r-done? [ drop dump-l ] [
over l-done? [ drop dump-r ] [
2dup decide
[ over l-next ] [ over r-next ] if
[ over r-next ] [ over l-next ] if
(merge)
] if
] if ; inline