// BufferedReaderなどを使うので,java.io.*を import する. import java.io.*; // Vectorを使うので java.util.* を importする. import java.util.*; class SortTest1 { // 比較回数を記録するための変数 static int compareCount=0; // s1とs2を比較してs1が辞書式順序で小さいときは負,等しいときは0,大きいときは正の整数を返す static int compare(String s1, String s2){ compareCount++; return s1.compareTo(s2); } // このメソッドの中で linesの並び替えをおこなう. // 最小値を元にしたソートu static void sort(String[] lines){ int i,j,minJ,len=lines.length; String minStr; for(i=0;i< len-1;i++){ // 最小値が仮にlines配列の i番目にあると仮定する. minStr=lines[i]; minJ=i; // それ以降のもので, minStrよりも小さいものが見つかったら,それを最小値と仮定する. for(j=i+1;j< len;j++){ if(compare(minStr,lines[j])>0){ minStr=lines[j]; minJ=j; } } // 最小値が minStrでそれが minJ番目に入っていると分かったので // iとminJの中身を交換する lines[minJ]=lines[i]; lines[i]=minStr; } } // IOExceptionを catchしていないので,throws IOExceptionをつける. public static void main(String args[]) throws IOException{ // ファイル名と思って BufferedReader BufferedReader is=new BufferedReader(new FileReader(args[0])); // 何行になるかわからないので,Vectorで記憶しておく Vector v=new Vector(); String s; // 1行読み込んでファイルの終端に到達しない間 while((s=is.readLine())!=null){ // Vectorの最後に要素を加える v.addElement(s); } // 入力ストリームを閉じる is.close(); // Vectorから配列に変換するために,領域を確保する String[] lines=new String[v.size()]; // Vectorから配列に変換する. v.copyInto(lines); // ソートする sort(lines); // ソートした結果を出力する. for(int i=0;i< lines.length;i++) System.out.println(lines[i]); System.err.println("比較回数は "+ compareCount +" 回です"); } }このプログラムは容易にわかるように,n行のファイルのソートに際して
n-1 Σ k = n * (n-1) /2 k=1回の比較を必要とする.そのため,59行の長さの 1013.htmlをファイルに落としてソートすると 1711回の比較が生ずる.
ちょっとした工夫で,比較回数を減らすことができる.以下のプログラムは, ランダムなファイルに対しては n*n/4 程度の比較回数,最悪の場合n*n/2程度 の比較回数となるプログラムである(挿入ソートと呼ばれる).
// BufferedReaderなどを使うので,java.io.*を import する. import java.io.*; // Vectorを使うので java.util.* を importする. import java.util.*; class SortTest2 { // このメソッドの中で linesの並び替えをおこなう. static int compareCount=0; static int compare(String s1, String s2){ compareCount++; return s1.compareTo(s2); } // 挿入ソート static void sort(String[] lines){ int i,j,len=lines.length; String s; // 0からi-1までがソート済みの時に,lines[i]を適切なところに挿入する for(i=1;i< len;i++){ // 挿入すべき行 s=lines[i]; for(j=i-1;j >=0;j--){ // lines[j]がsよりも小さくなる jを求める. if(compare(s,lines[j])>0){ break; } // 右に1つ要素をずらす. lines[j+1]=lines[j]; } // sを挿入する lines[j+1]=s; } } // IOExceptionを catchしていないので,throws IOExceptionをつける. public static void main(String args[]) throws IOException{ // ファイル名と思って BufferedReader BufferedReader is=new BufferedReader(new FileReader(args[0])); // 何行になるかわからないので,Vectorで記憶しておく Vector v=new Vector(); String s; // 1行読み込んでファイルの終端に到達しない間 while((s=is.readLine())!=null){ // Vectorの最後に要素を加える v.addElement(s); } // 入力ストリームを閉じる is.close(); // Vectorから配列に変換するために,領域を確保する String[] lines=new String[v.size()]; // Vectorから配列に変換する. v.copyInto(lines); // ソートする sort(lines); // ソートした結果を出力する. for(int i=0;i< lines.length;i++) System.out.println(lines[i]); System.err.println("比較回数は "+ compareCount +" 回です"); } }これを実行してみると,1013.htmlに対しては,999回の比較回数となる.