in reply to Algorithm Pop Quiz: Sorting

Oh bugger me, I had to see this at 1:00AM when I was about to go in for the night...

I'm not sure that I see a quicksort coming out of this. With the limitation on accessing the stack and all, plus no allowances for making arrays or new stacks, handling the recursion would be a nightmare. I once had to write a non-recursive implementation of quicksort as a class exercise, and it damn near drove me into the arms of the music department as a result.

Here's a bubblesort. I'm not sure how you count instructions. If I count every assignment, count each conditional as one (each of the two while's and an if), then a cond-clause as well (the else), plus one count for calls like pop, push and rotate_up, then I get somewhere around 24. That's probably not quite right, though, or your challenge would have been for a lower number.

Bubble-sort is still an O(N2) algorithm, though it is better in most cases than a selection sort. There is an early-termination form of the algorithm, but I'm already up past my bedtime. If I get a chance to look at this again before deadline, I'll see if I can adapt that. Big raspberries to the people who say that studying computer science in universities is a waste of time (and I know a lot of them at my day-job).

If I take complete leave of my senses, I'll see if I can remember that non-recursive q-sort...

--rjray

# Assume that rotate_up as defined in the original problem # statement has been defined. sub sordid { local $len = pop(@stack); local $bum = $len; local ($x, $y, $limit); while ($bum > 1) { $limit = $bum; while (--$limit) { $x = pop(@stack); $y = pop(@stack); if ($x gt $y) { push(@stack, $x); push(@stack, $y); } else { push(@stack, $y); push(@stack, $x); } rotate_up($bum); } # At end of the $limit loop, top element is the max, and # top+1 to end is semi-sorted. One more rotate_up() # is needed before moving the floor up one notch. rotate_up($bum); $bum--; } push(@stack, $len); } @stack = qw(d b f a e c 6); # <-- bottom .. top --> print "(@stack)\n"; # Prints: (d b f a e c 6) sordid(); print "(@stack)\n"; # Prints: (f e d c b a 6)

Replies are listed 'Best First'.
Re: Re: Algorithm Pop Quiz: Sorting
by Jasper (Chaplain) on Mar 25, 2002 at 14:08 UTC
    I knocked together an almost identical bit of code, apart from the gt bit, which really is the same:
    sub sort_stack { local $depth = pop @stack; local $sort_depth = $depth; for (1..$depth) { for (1..$sort_depth) { local $top = pop @stack; local $next = pop @stack; if ($top gt $next) { $top ^= $next; $next ^= $top; $top ^= $next; } push @stack, $next, $top; rotate_up($sort_depth); } rotate_up($sort_depth); --$sort_depth; } push @stack, $depth; }
    Although I hadda go and use an xor swap, to make it look quite cool..
      Sure, it looks cool. It's just wrong :)

      The problem with xor on strings is it will extend short ones. There are now 0 bytes there that weren't there before, and length changes.

      $ perl -e'$a="a"; $b="bbb"; $a^=$b; $b^=$a; $a^=$b; print "/$a/,/$b/\n +"; print length($a),"\n"; print length($b),"\n"' /bbb/,/a/ 3 3

      --
      Mike
        Mike, thanks, I think. How odd. I had no idea this happened. That'll teach me. Still, I've never had a computer science lesson in my life, so how am I expected to know these things!?! :) Cheers, Jasper
      BZZZT

      I'm going to disallow this one as it's relying on a feature that's language dependent for its implementation (the XOR swap for stings). The sprit is there, but you're starting to wander. This kind of behavior needs to be discouraged early! Use the extra register for the swap. :)

      These are all so good though. The excitement is terrible. Just terrible!

Improved Bubble-Sort (Re: Re: Algorithm Pop Quiz: Sorting)
by rjray (Chaplain) on Mar 25, 2002 at 23:31 UTC

    OK, here's the early-exit version. This proved more straight-forward than I was expecting. I was so sure that applying the knowledge of last-exchange would be difficult, I overlooked how trivial it actually is.

    (This is still a bubble-sort, but it no longer is compelled to iterate [ $length - 1 ] times. Rather, the false-bottom can jump over several iterations if there is a clump of sorted elements at the end. Given the six-element sample list here, it saves only 3 iterations of the inner-loop, 17 versus 20 in my original.)

    # Assume that rotate_up as defined in the original problem # statement has been defined. sub sordid { local $len = pop(@stack); local $bum = $len; local ($x, $y, $limit, $last_swap); while ($bum > 1) { $limit = $bum; $last_swap = 0; while (--$limit) { $x = pop(@stack); $y = pop(@stack); if ($x gt $y) { push(@stack, $x); push(@stack, $y); $last_swap = $bum - $limit; } else { push(@stack, $y); push(@stack, $x); } rotate_up($bum); } # At end of the $limit loop, top element is the max, and # top+1 to end is semi-sorted. One more rotate_up() # is needed before moving the floor up one notch. rotate_up($bum); $bum = $last_swap; } push(@stack, $len); } @stack = qw(d b f a e c 6); # <-- bottom .. top --> print "(@stack)\n"; # Prints: (d b f a e c 6) sordid(); print "(@stack)\n"; # Prints: (f e d c b a 6)

    --rjray

Re: Re: Algorithm Pop Quiz: Sorting
by RMGir (Prior) on Mar 25, 2002 at 12:21 UTC
    Wow, I like this one.

    Cool!
    --
    Mike