2010年5月15日土曜日

マージソート

何となく作りたくなったので,マージソート.

■コード
/** Marge sort(マージソート) */
public void margeSort(int[] a){
int n=a.length;
if(n==1) return;
// b.length+c.length=a.length
int[] b=new int[n/2];
int[] c=new int[n-n/2];
System.arraycopy(a, 0, b, 0, b.length);
System.arraycopy(a, n/2, c, 0, c.length);
margeSort(b);
margeSort(c);
// ソートされたbとcをaにマージ
for(int i=0, j=0, k=0;i<n;i++)
if(k==c.length)
a[i]=b[j++];
else if(j==b.length)
a[i]=c[k++];
else if(b[j]<c[k])
a[i]=b[j++];
else
a[i]=c[k++];
}


■特徴
・分割統治法を用いたソートアルゴリズム
・最悪計算量O(nlogn)
・安定ソートである

■原理
ある配列(数列)aとbが以下であるとします.
a1, …, am
b1, …, bn
この時,
ai<=ai+1
bj<=bj+1
とすれば,つまり,aもbもソートされているとすれば,それらをマージした以下の配列(数列)cが作れる.
c1, …, cm+n
これを再帰的に適用します.

■適用例
8,3,4,6,2,5,7,1

まずは,"分割"します.

83462571

83462571

83462571

83462571

配列の要素が一つになるまで"分割"しました.要素数が1の配列が"ソートされている事"は,明らかですので,ここからはソートされている配列を"統治"していきます.

38462517

ここで,要素数が2の配列が4つ出来ましたが,それぞれソートされています.

34681257

12345678

というわけでゴール.正しくソートされました.

0 件のコメント: