算法思想
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并
算法描述
1.把长度为n的输入序列分成两个长度为n/2的子序列;
2.对这两个子序列分别采用归并排序;
3.将两个排序好的子序列合并成一个最终的排序序列。
代码实现
C++
#include<iostream>
using namespace std;
void Merge(int* arr, int start1, int end1, int start2, int end2)
{
int len_left = end1 - start1 + 1;
int len_right = end2 - start2 + 1;
int* arr_left = new int[len_left];
int* arr_right = new int[len_right];
for (int i = 0; i < len_left; ++i) arr_left[i] = arr[start1 + i];
for (int i = 0; i < len_right; ++i) arr_right[i] = arr[start2 + i];
int left = 0;
int right = 0;
int p = start1;
while (left < len_left && right < len_right)
{
if (arr_left[left] < arr_right[right])
{
arr[p] = arr_left[left];
++left;
}
else
{
arr[p] = arr_right[right];
++right;
}
++p;
}
while (left < len_left)
{
arr[p] = arr_left[left];
++left;
++p;
}
while (right < arr_right[right])
{
arr[p] = arr_right[right];
++right;
++p;
}
delete[] arr_left;
delete[] arr_right;
}
void MergeSort(int* arr, int start, int end)
{
if (start < end)
{
int mid = start + (end - start) / 2;
//分
MergeSort(arr, start, mid);
MergeSort(arr, mid + 1, end);
//合
Merge(arr, start, mid, mid+1, end);
}
}
int main()
{
int num[] = { 8,1,7,2,6,3,5,4 };
int len = sizeof(num) / sizeof(num[0]);
for (int i = 0; i < len; ++i)
{
cout << num[i];
}
cout << endl;
MergeSort(num, 0, len-1);
for (int i = 0; i < len; ++i)
{
cout << num[i];
}
}
Python
def Merge(nums, start1, end1, start2, end2):
nums_left = nums[start1:end1+1]
nums_right = nums[start2:end2+1]
left, right = 0, 0
p = start1
while left < len(nums_left) and right < len(nums_right):
if nums_left[left] < nums_right[right]:
nums[p] = nums_left[left]
left += 1
else:
nums[p] = nums_right[right]
right += 1
p += 1
while left < len(nums_left):
nums[p] = nums_left[left]
left += 1
p += 1
while right < len(nums_right):
nums[p] = nums_right[right]
right += 1
p += 1
def MergeSort(nums, start, end):
if start < end:
mid = start + (end - start) // 2
MergeSort(nums, start, mid)
MergeSort(nums, mid + 1, end)
Merge(nums, start, mid, mid + 1, end)