挿入ソートとデータ列の関係(前編)

挿入ソートは、既にソート済みのデータ列に、
ソートした状態を維持しながらデータを追加するのは早いそうなので、
何種類かデータ列を用意して、ソートに掛かる時間を計測してみました。

という訳で、ランダムと昇順と降順の3種類を用意しました。

use strict;
use warnings;
use v5.10;

use Array::Shuffle qw/shuffle_array/;

print "\n--- random data ---\n";
{
    my @data = 1..9;
    shuffle_array( @data );
    say join( ', ', @data );
    say join( ', ', insert_sort(@data) );
}

print "\n--- 9,8,7 ... (descending order) ---\n";
{
    my @data = reverse( 1..9 );
#    shuffle_array( @data );
    say join( ', ', @data );
    say join( ', ', insert_sort(@data) );
}

print "\n--- 1,2,3 ... (ascending order) ---\n";
{
    my @data = 1..9;
#    shuffle_array( @data );
    say join( ', ', @data );
    say join( ', ', insert_sort(@data) );
}

sub insert_sort {
    my @data = @_;

    my $move = 0;
    my $cnt = scalar( @data );
    for (my $i=1; $i<$cnt; $i++) {
        if ( $data[$i] < $data[$i-1] ) {
            printf( "i =%2d: skip!\n", $i );
        }
        else {
            my $wk = $data[$i];
            $move++;
            my $j = $i;
            for (; 0<$j; $j--) {
                if ( $wk <= $data[$j-1] ) {
                    last;
                }
                else {
                    $data[$j] = $data[$j-1];
                    $move++;
                }
            }

            $data[$j] = $wk;
            $move++;

            printf( "i =%2d: insert!\n", $i );
        }
    }

    printf( "move = %d\n", $move );

    return @data;
}

実行結果はこんな感じ。
$ perl aaa.pl

--- random data ---
7, 6, 4, 3, 5, 1, 8, 9, 2
i = 1: skip!
i = 2: skip!
i = 3: skip!
i = 4: insert!
i = 5: skip!
i = 6: insert!
i = 7: insert!
i = 8: insert!
move = 24
9, 8, 7, 6, 5, 4, 3, 2, 1

--- 9,8,7 ... (descending order) ---
9, 8, 7, 6, 5, 4, 3, 2, 1
i = 1: skip!
i = 2: skip!
i = 3: skip!
i = 4: skip!
i = 5: skip!
i = 6: skip!
i = 7: skip!
i = 8: skip!
move = 0
9, 8, 7, 6, 5, 4, 3, 2, 1

--- 1,2,3 ... (ascending order) ---
1, 2, 3, 4, 5, 6, 7, 8, 9
i = 1: insert!
i = 2: insert!
i = 3: insert!
i = 4: insert!
i = 5: insert!
i = 6: insert!
i = 7: insert!
i = 8: insert!
move = 52
9, 8, 7, 6, 5, 4, 3, 2, 1

入れ替えが必要かどうかチェックして、
“skip!” or “insert!”を出力させています。
あと、データの移動回数を数えて、最後にその合計を出力しました。

移動回数の合計は、何回かこれを繰り返して、
平均をとって比較するのが良いと思います。

続く。

Leave a Comment