santosh_br has asked for the wisdom of the Perl Monks concerning the following question:


Please clarify this doubght in this script... which I got from one of the website.

In the below subroutine... Can you please tell me what is this while condition does??

while ( not $sorted )

If I change the $sorted value to any other digit or blank the script stops. What exactly the 'not' effect on the while?? Is keeping $sorted to 0 makes it empty variable?? getting confused.. here...
sub bubbleSort { my @list = @_; my $sorted = 0; while ( not $sorted ) { $sorted = 1; # Innocent until proven guilty. for my $current ( 1 .. $#list ) { my $previous = $current - 1; if ( $list$current < $list$previous ) { ($list$current, $list$previous) = ($list$previous, $list$current); $sorted = 0; } } } return @list; }

Replies are listed 'Best First'.
Re: while condition bubbleSort
by GrandFather (Saint) on Jul 17, 2008 at 03:46 UTC

    $sorted is a flag that is set false each time through the loop when a swap is required. It is set false initially so that the while loop executes at least once.

    Note that Perl provides sort so writing your own is seldom needed.


    Perl is environmentally friendly - it saves trees
Re^2: while condition bubbleSort
by eosbuddy (Scribe) on Jul 17, 2008 at 04:11 UTC
    use strict; use warnings; my @list2 = sort { $a <=> $b } @list;
    I thought should solve your problem (unless bubble sort is kind of a exercise that you need to do).
Re: while condition bubbleSort
by pjotrik (Friar) on Jul 17, 2008 at 08:18 UTC

    The while (not $sorted) checks whether there was a swap in the previous cycle. If not, all neighboring pairs in the list satisfy the condition $list[$i]<=$list[$i+1], i.e. the list is sorted. Another common optimization of bubblesort would be to only sort the part of the list that isn't sorted yet. (Hope you only take this as an exercise, sort would do this quicker and easier)

    sub bubbleSort { my @list = @_; my $cutoff; my $last_changed = @list; while ( $last_changed ) { $cutoff = $last_changed; $last_changed = 0; for my $current ( 1 .. $cutoff ) { my $previous = $current - 1; if ( $list[$current] < $list[$previous] ) { ($list[$current], $list[$previous]) = ($list[$previous +], $list[$current]); $last_changed = $previous; } } } return @list; }

    And, please, use <code> tags to enclose your code next time