in reply to Re: Randomize an array
in thread Randomize an array
We break from this post to give a brief description of quicksort for those who don't know.
Quicksort is a recursive algorithm that picks a pivot element out of the array and then compares all the other elements to it. This results in two arrays and the pivot, where one array is all items "greater then" the pivot and the other is all items "less then" the pivot. Quicksort is then used to sort these two arrays. Since its done recursivly, it ends up with an array of pivot points in order. The code might look something like this:
(Disclaimer: I didn't test that and I havn't looked any of this up, so I could be completly wrong and that code might not work)sub Qsort # WRONG! See update below! { my $pivot = shift; # picking the pivot is usually more # involved. Afterall, you don't want # an extreme, you want both arrays to # be roughly the same size. return $pivot unless @_; my( @lt, @gt ); push( $_ gt $pivot ? @gt : @lt ) for @_; return( Qsort( @lt ), $pivot, Qsort( @gt ) ); }
So you see, the amount of time @a = sort {(-1,1)[rand 2]} @a will take is finite and well defined, regardless of the function used to determine which side of the pivot to place each element. So the only reason it would dumb core would be that it ran out of memory, but it should never become hung (unless, as I said, it ran out of memory... those sneaky recursive algorithms). The only thing that varies in a quicksort is how well the pivot is chosen. If you pick an extreme (where everything ends up on one side of the pivot) then Qsort will take much longer then if you pick the middle where everything is balanced. So the point of all this is that I doubt the implementation has gotten better, but rather the hardware (128 MB ram sure beats 2 or 4 MB).
Update:
So I did a little research on Quicksort and realized that it usually operates on the array in place, which mine clearly doesn't. And that it does even less work then mine did. How about:
For more about sorting, check out these great documents I found: Here and here.sub Qsort { my( $arrayRef, $lowIndex, $highIndex ) = @_; return undef if $highIndex le $lowIndex; my $pivotIndex = partition( $arrayRef, $lowIndex, $highIndex ); Qsort( $arrayRef, $lowIndex, $pivotIndex - 1 ); Qsort( $arrayRef, $pivotIndex + 1, $highIndex ); } # And then, of course, I need to provide &partition sub partition { my( $arrayRef, $lowIndex, $highIndex ) = @_; my $pivot = $highIndex + $lowIndex >> 1; my $pivotElement = $$arrayRef[$pivot]; while( $highIndex > $lowIndex ) { ++$lowIndex while $$arrayRef[$lowIndex] <= $pivotElement and $ +_[2] > $lowIndex; --$highIndex while $pivotElement <= $$arrayRef[$highIndex] and + $highIndex > $_[1]; Swap( $arrayRef, $lowIndex, $highIndex ) if $highIndex > $lowI +ndex; } if( $highIndex > $pivot ) { Swap( $arrayRef, $pivotIndex, $highIndex ); $pivot = $highIndex; } elsif( $pivot > $lowIndex ) { Swap( $arrayRef, $pivotIndex, $lowIndex ); $pivot = $lowIndex; } return $pivot; } sub Swap { ${$_[0]}->[$_[1],$_[2]] = ${$_[0]}->[$_[1],$_[2]] } # Warning, untested code...
BTW: After at least an hour of working on this post I have realized that a true quicksort would, in fact, go crazy given { (-1,1)[rand 2] } and I am now somewhat mystified as to why it converges at all. I think its time to go eat something and I will return to this later.
Update:
So I slept on it, and I am now re-convinced that Qsort will be finite regardless of the random nature of its partition. So I go back to the original point of this post, Tye, that Qsort should only fail if it runs out of memory for all those recursive calls, and that it should end in a finite amount of time not to exceed some constant times N squared. (N being the number of elements to be sorted.)
My apologies to anyone that I have confused with this post. Maybe it will inspire you to learn more about sort.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
RE (tilly) 3 (tis true): Randomize an array
by tilly (Archbishop) on Sep 08, 2000 at 06:01 UTC | |
by Adam (Vicar) on Sep 09, 2000 at 00:33 UTC | |
by tilly (Archbishop) on Sep 09, 2000 at 00:55 UTC |