归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个典型的应用。
思路:
- 把长度为n的输入序列分为两个长度为n/2的的序列
- 对这两个子序列分别采用归并排序
- 将两个排好序的子序列合并成一个最终的排序序列
时间复杂度:最好:O(nlogn) 最坏:O(nlogn) 平均:O(nlogn)
空间复杂度:O(n)
非递归代码如下:
void Meger(int *arr, int len, int wide)
{
int l1 = 0;
int h1 = l1 + wide - 1;
int l2 = h1 + 1;
int h2 = l2 + wide - 1 > len - 1 ? len - 1 : l2 + wide - 1;
int *brr = new int[len];
int index = 0;
while (l1 < len)
{
while (l1 <= h1 && l2 <= h2)
{
if (arr[l1] < arr[l2])
{
brr[index++] = arr[l1++];
}
else
{
brr[index++] = arr[l2++];
}
}
while (l1 <= h1)
{
brr[index++] = arr[l1++];
}
while (l2 <= h2)
{
brr[index++] = arr[l2++];
}
l1 = h2 + 1;
h1 = l1 + wide - 1 > len - 1 ? len - 1 : l1 + wide - 1;;
l2 = h1 + 1;
h2 = l2 + wide - 1>len - 1 ? len - 1 : l2 + wide - 1;
}
for (int i = 0; i < len; i++)
{
arr[i] = brr[i];
}
delete[]brr;
}
void MegerSort(int *arr, int len)
{
for (int i = 1; i < len; i *= 2)
{
Meger(arr,len, i);
}
}
递归代码如下:
void meger(int *arr, int left, int mid, int right)
{
int i = left, j = mid + 1, k = 0;
int *p = new int[right];
while (i <= mid && j <= right)
{
if (arr[i] <= arr[j])
{
p[k++] = arr[i++];
}
else
{
p[k++] = arr[j++];
}
}
while (i <= mid)
{
p[k++] = arr[i++];
}
while (j <= right)
{
p[k++] = arr[j++];
}
for (int i = left,j = 0;j < k && i <= right; i++)
{
arr[i] = p[j++];
}
}
void megersort(int *arr, int left, int right)
{
if (left == right)
{
return;
}
else
{
int mid = (right - left) / 2 + left;
megersort(arr, left, mid);
megersort(arr, mid + 1, right);
meger(arr, left, mid, right);
}
}