マージソートは整列されていないリストを2つのリストに分割して、それぞれを整列させた後、それらをマージして整列済みのひとつのリストを作ります。
マージを利用してリストを整列するのでマージソートという名がついています。
分割された部分的なリストをサブリストと呼びます。サブリストもマージソートを使って整列させます。2. の手順にはこのアルゴリズムを再帰的に適用することになります。
リストをいったんバラバラにしたあと、マージによってリストを再構築します。
マージとはいくつかの整列済みのリストをひとつのリストにまとめる操作です。
整列済みのリストAとリストBをマージして整列されたリストCを作ると考えます。
以上の手順でマージは完了します。
配列を昇順に整列させます。
void mergeSort(int numbers[], int temp[], int array_size)
{
m_sort(numbers, temp, 0, array_size - 1);
}
void m_sort(int numbers[], int temp[], int left, int right)
{
int mid;
if (right > left)
{
mid = (right + left) / 2; /* 配列を分割する位置 */
m_sort(numbers, temp, left, mid);
m_sort(numbers, temp, mid+1, right);
merge(numbers, temp, left, mid+1, right);
}
}
void merge(int numbers[], int temp[], int left, int mid, int right)
{
int i, left_end, num_elements, tmp_pos;
left_end = mid - 1;
tmp_pos = left;
num_elements = right - left + 1; /* 配列の要素数 */
/* 2つのリストに要素が残っている */
while ((left <= left_end) && (mid <= right))
{
if (numbers[left] <= numbers[mid])
{
temp[tmp_pos] = numbers[left];
tmp_pos = tmp_pos + 1;
left = left +1;
}
else
{
temp[tmp_pos] = numbers[mid];
tmp_pos = tmp_pos + 1;
mid = mid + 1;
}
}
/* 左側のリスト */
while (left <= left_end)
{
temp[tmp_pos] = numbers[left];
left = left + 1;
tmp_pos = tmp_pos + 1;
}
/* 右側のリスト */
while (mid <= right)
{
temp[tmp_pos] = numbers[mid];
mid = mid + 1;
tmp_pos = tmp_pos + 1;
}
/* 昇順に整列するようひとつのリストにまとめる */
for (i=0; i <= num_elements; i++)
{
numbers[right] = temp[right];
right = right - 1;
}
}
マージソートのデモンストレーション プログラム: merge_sort.c
def merge_sort(aList):
if len(aList) <= 1:
return aList
mid = len(aList) // 2
left = aList[:mid]
right = aList[mid:]
left = merge_sort(left)
right = merge_sort(right)
return list(merge(left, right))
def merge(left, right):
sorted_list = []
left_index = 0
right_index = 0
while left_index < len(left) and right_index < len(right):
if left[left_index] <= right[right_index]:
sorted_list.append(left[left_index])
left_index += 1
else:
sorted_list.append(right[right_index])
right_index += 1
if left:
sorted_list.extend(left[left_index:])
if right:
sorted_list.extend(right[right_index:])
return sorted_list
if __name__ == '__main__':
from random import shuffle
l = range(15)
lcopy = l[:]
shuffle(l)
print('Unsorted')
print l
assert l != lcopy
print ('Sorted')
l = merge_sort(l)
print l
assert l == lcopy