挿入ソートとデータ列の関係(前編)
挿入ソートは、既にソート済みのデータ列に、
ソートした状態を維持しながらデータを追加するのは早いそうなので、
何種類かデータ列を用意して、ソートに掛かる時間を計測してみました。
という訳で、ランダムと昇順と降順の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