マージソート
| 日本語 | 併合並び替え |
| 英語 | merge sort、mergesort |
| ふりがな | まーじそーと |
| フリガナ | マージソート |
分割した要素をマージしていくソート。
ソートのアルゴリズムのひとつ。
最速レベルのソートであり、安定ソートでもある、とソートアルゴリズムの優等生。
配列を一度バラバラに分解し、バラバラになった要素を隣同士くっつけていく際に「小さい方を左に、大きい方を右に」するようくっつけていくと、最終的にはソートされている、というアルゴリズム。
この「くっつける」という作業を「マージ」と呼ぶため「マージソート」と呼ぶ。
マージされた塊は「すでにソートされている」ため、これを小さい順にマージする処理は「要素の比較」の回数が少なくて済み、ソートのアルゴリズムの中でもトップクラスの速さを誇る。
最速レベルであり、安定ソートであり、様々なソートに利用できる事もあり、よく使われるアルゴリズムである。
Arraysクラスのsort()メソッドでクラスをソートする場合にはこのアルゴリズムを改良した「修正マージソート」を使用しているため、Arraysクラスのsort()メソッドを用いたソートはかなり優秀なソートということができる。
ソートのアルゴリズムのひとつ。
最速レベルのソートであり、安定ソートでもある、とソートアルゴリズムの優等生。
配列を一度バラバラに分解し、バラバラになった要素を隣同士くっつけていく際に「小さい方を左に、大きい方を右に」するようくっつけていくと、最終的にはソートされている、というアルゴリズム。
この「くっつける」という作業を「マージ」と呼ぶため「マージソート」と呼ぶ。
マージされた塊は「すでにソートされている」ため、これを小さい順にマージする処理は「要素の比較」の回数が少なくて済み、ソートのアルゴリズムの中でもトップクラスの速さを誇る。
最速レベルであり、安定ソートであり、様々なソートに利用できる事もあり、よく使われるアルゴリズムである。
Arraysクラスのsort()メソッドでクラスをソートする場合にはこのアルゴリズムを改良した「修正マージソート」を使用しているため、Arraysクラスのsort()メソッドを用いたソートはかなり優秀なソートということができる。
参考サイト
// Sample.java
public class Sample
{
public static void main( String[] args )
{
// 出力する配列を用意します。
int[] ints = new int[]{ 4, 9, 3, 5, 8 };
for( int iF1 = 0; iF1 < ints.length; ++iF1 )
{
System.out.print( ints[iF1] + ", " );
}
System.out.println();
// 4, 9, 3, 5, 8,
// マージソートします。
mergeSort( ints );
for( int iF1 = 0; iF1 < ints.length; ++iF1 )
{
System.out.print( ints[iF1] + ", " );
}
System.out.println();
// 3, 4, 5, 8, 9,
}
/**
* マージソートします。
*/
private static void mergeSort( int[] array )
{
if( array.length <= 1 )
{
// 要素数が1以下なら何もしません。
return;
}
// 中央から左側のサイズを取得します。
int leftSize = array.length / 2;
// 中央から右側のサイズを取得します。
int rightSize = array.length - leftSize;
// 中央から左側のサイズの配列を作成します。
int[] leftArray = new int[leftSize];
// 中央から右側のサイズの配列を作成します。
int[] rightArray = new int[rightSize];
// それぞれコピーします。
int iF1;
for( iF1 = 0; iF1 < leftSize; ++iF1 )
{
leftArray[iF1] = array[iF1];
}
for( iF1 = 0; iF1 < rightSize; ++iF1 )
{
rightArray[iF1] = array[leftSize + iF1];
}
// それぞれ再帰呼び出しします。
mergeSort( leftArray );
mergeSort( rightArray );
// マージします。
int leftPos = 0;
int rightPos = 0;
while(
( leftPos < leftSize ) ||
( rightPos < rightSize )
)
{
// 左右両方とも配列の中にいる間、ループします。
if( rightSize <= rightPos )
{
// 右側が配列の最後まで来ている場合。
// 左側を追加します。
array[leftPos + rightPos] = leftArray[leftPos];
++leftPos;
}
else if( leftSize <= leftPos )
{
// 左側が配列の最後まで来ている場合。
// 右側を追加します。
array[leftPos + rightPos] = rightArray[rightPos];
++rightPos;
}
else if( leftArray[leftPos] > rightArray[rightPos] )
{
// 左側の方が右側より大きい場合。
// 右側を追加します。
array[leftPos + rightPos] = rightArray[rightPos];
++rightPos;
}
else
{
// それ以外の場合(左側の方が右側より小さい場合)。
// 左側を追加します。
array[leftPos + rightPos] = leftArray[leftPos];
++leftPos;
}
}
}
}
public class Sample
{
public static void main( String[] args )
{
// 出力する配列を用意します。
int[] ints = new int[]{ 4, 9, 3, 5, 8 };
for( int iF1 = 0; iF1 < ints.length; ++iF1 )
{
System.out.print( ints[iF1] + ", " );
}
System.out.println();
// 4, 9, 3, 5, 8,
// マージソートします。
mergeSort( ints );
for( int iF1 = 0; iF1 < ints.length; ++iF1 )
{
System.out.print( ints[iF1] + ", " );
}
System.out.println();
// 3, 4, 5, 8, 9,
}
/**
* マージソートします。
*/
private static void mergeSort( int[] array )
{
if( array.length <= 1 )
{
// 要素数が1以下なら何もしません。
return;
}
// 中央から左側のサイズを取得します。
int leftSize = array.length / 2;
// 中央から右側のサイズを取得します。
int rightSize = array.length - leftSize;
// 中央から左側のサイズの配列を作成します。
int[] leftArray = new int[leftSize];
// 中央から右側のサイズの配列を作成します。
int[] rightArray = new int[rightSize];
// それぞれコピーします。
int iF1;
for( iF1 = 0; iF1 < leftSize; ++iF1 )
{
leftArray[iF1] = array[iF1];
}
for( iF1 = 0; iF1 < rightSize; ++iF1 )
{
rightArray[iF1] = array[leftSize + iF1];
}
// それぞれ再帰呼び出しします。
mergeSort( leftArray );
mergeSort( rightArray );
// マージします。
int leftPos = 0;
int rightPos = 0;
while(
( leftPos < leftSize ) ||
( rightPos < rightSize )
)
{
// 左右両方とも配列の中にいる間、ループします。
if( rightSize <= rightPos )
{
// 右側が配列の最後まで来ている場合。
// 左側を追加します。
array[leftPos + rightPos] = leftArray[leftPos];
++leftPos;
}
else if( leftSize <= leftPos )
{
// 左側が配列の最後まで来ている場合。
// 右側を追加します。
array[leftPos + rightPos] = rightArray[rightPos];
++rightPos;
}
else if( leftArray[leftPos] > rightArray[rightPos] )
{
// 左側の方が右側より大きい場合。
// 右側を追加します。
array[leftPos + rightPos] = rightArray[rightPos];
++rightPos;
}
else
{
// それ以外の場合(左側の方が右側より小さい場合)。
// 左側を追加します。
array[leftPos + rightPos] = leftArray[leftPos];
++leftPos;
}
}
}
}
// Sample.java
public class Sample
{
public static void main( String[] args )
{
// 出力する配列を用意します。
int[] ints = new int[]{ 4, 9, 3, 5, 8 };
for( int iF1 = 0; iF1 < ints.length; ++iF1 )
{
System.out.print( ints[iF1] + ", " );
}
System.out.println();
// 4, 9, 3, 5, 8,
// マージソートします。
mergeSort( ints );
for( int iF1 = 0; iF1 < ints.length; ++iF1 )
{
System.out.print( ints[iF1] + ", " );
}
System.out.println();
// 3, 4, 5, 8, 9,
}
/**
* マージソートします。
*/
private static void mergeSort( int[] array )
{
if( array.length <= 1 )
{
// 要素数が1以下なら何もしません。
return;
}
// 中央から左側のサイズを取得します。
int leftSize = array.length / 2;
// 中央から右側のサイズを取得します。
int rightSize = array.length - leftSize;
// 中央から左側のサイズの配列を作成します。
int[] leftArray = new int[leftSize];
// 中央から右側のサイズの配列を作成します。
int[] rightArray = new int[rightSize];
// それぞれコピーします。
int iF1;
for( iF1 = 0; iF1 < leftSize; ++iF1 )
{
leftArray[iF1] = array[iF1];
}
for( iF1 = 0; iF1 < rightSize; ++iF1 )
{
rightArray[iF1] = array[leftSize + iF1];
}
// それぞれ再帰呼び出しします。
mergeSort( leftArray );
mergeSort( rightArray );
// マージします。
int leftPos = 0;
int rightPos = 0;
while(
( leftPos < leftSize ) ||
( rightPos < rightSize )
)
{
// 左右両方とも配列の中にいる間、ループします。
if( rightSize <= rightPos )
{
// 右側が配列の最後まで来ている場合。
// 左側を追加します。
array[leftPos + rightPos] = leftArray[leftPos];
++leftPos;
}
else if( leftSize <= leftPos )
{
// 左側が配列の最後まで来ている場合。
// 右側を追加します。
array[leftPos + rightPos] = rightArray[rightPos];
++rightPos;
}
else if( leftArray[leftPos] > rightArray[rightPos] )
{
// 左側の方が右側より大きい場合。
// 右側を追加します。
array[leftPos + rightPos] = rightArray[rightPos];
++rightPos;
}
else
{
// それ以外の場合(左側の方が右側より小さい場合)。
// 左側を追加します。
array[leftPos + rightPos] = leftArray[leftPos];
++leftPos;
}
}
}
}




