/// <summary>
/// 时间复杂度为O(N)
/// </summary>
public static void Merge(int[] arr,int L,int M,int R)
{
int[] temp = new int[R - L + 1];
int i = 0;
int left_point = L;
int right_point = M + 1;
//左右指针移动,最小的数填充到中间数组
while (left_point <= M && right_point <= R)
temp[i++] = arr[left_point] <= arr[right_point] ? arr[left_point++] : arr[right_point++];
//左或右指针越界时,填充剩余的数
while (left_point <= M)
temp[i++] = arr[left_point++];
while (right_point <= R)
temp[i++] = arr[right_point++];
for (i = 0; i < temp.Length; i++)
arr[L + i] = temp[i];
}
/// <summary>
/// 递归排序 τ(N)=2∗τ(N/2)+ο(N*1)
/// </summary>
public static void RecursiveMergeSort(int[] arr,int L,int R)
{
if (L == R)
return;
int mid = L + ((R - L) >> 1);
RecursiveMergeSort(arr, L, mid);
RecursiveMergeSort(arr, mid + 1, R);
Merge(arr, L, mid, R);
}
/// <summary>
/// 非递归实现 O(N*logN)
/// </summary>
/// <param name="arr"></param>
public static void MergeSort(int[] arr)
{
if (arr == null || arr.Length < 2)
return;
int N = arr.Length;
int mergeSize = 1; //当前有序的,左右长度
while (mergeSize < N)
{
int L = 0;
while (L < N)
{
int M = L + mergeSize - 1;
if (M >= N)
break;
int R = Math.Min(M + mergeSize, N - 1);
Merge(arr, L, M, R);
L = R + 1;
}
if (mergeSize > N >> 1)
break;
mergeSize <<= 1;
}
}
归并排序的核心精髓在于,将比较的行为省下来变为有序的部分,先按最小的范围都先固定好排序(固定的序列中后续不需要做多余的计算),再不断的通过同等级范围进行PK排序进行倍数级扩张范围,直至最终的排序,时间复杂度为