归并排序:
两个有序数组合并为一个有序数组
步骤:
1 两个指针分别指向两个有序数组;
2 循环遍历并且比较,符合要求的数据存放到最终的内存段中,并且指针后挪;
3 直到有一个数组存放完毕,循环结束;
4 将没有放完的数组拷贝到最终的内存段中;
1 源文件
#include<stdio.h>
#include<string.h>
//归并排序
void merge_sort(int* arr, int len);
//递归拆分 left:左边一半第一个元素下标,right:右边一半最后一个元素的下标
void split(int* arr, int left, int right);
//合并 left:左边一半第一个元素下标,mid:左边一半最后一个元素下标,right:右边一半最后一个元素的下标
void combine(int* arr, int left, int mid, int right);
void print(int* arr, int len);
int main()
{
int arr[10] = { 15,32,89,456,133,20,46,57,77,966 };
printf("before :");
print(arr, 10);
merge_sort(arr, 10);
printf("after :");
print(arr, 10);
return 0;
}
void merge_sort(int* arr, int len)
{
split(arr, 0, len - 1);
}
void split(int* arr, int left, int right)
{
if(left < right)//保证拆分到只有一个元素就停止
{
//算中间值
//int mid = (right - left) / 2 + left;
int mid = (left+right)/2;
//拆分
split(arr, left, mid);//拆左边
split(arr, mid + 1, right);//拆右边
//合并
combine(arr, left, mid, right);
print(arr + left, right - left + 1);
}
}
void combine(int* arr, int left, int mid, int right)
{
//申请临时内存段
int len = right - left + 1;
int* pTemp = new int[len];
//循环比较并把数据有序放到pTemp
int l = left;//左边一半
int r = mid+1;//右边一半
int k = 0;//pTemp的下标
while (l <= mid && r <= right)
{
if (arr[l] < arr[r])
{
pTemp[k++] = arr[l++];
}
else
{
pTemp[k++] = arr[r++];
}
}
//把剩下的也放到pTemp
#if 1
while(l<=mid)pTemp[k++] = arr[l++];
while(r<=right)pTemp[k++] = arr[r++];
#else
if (l <= mid)//左边没放完
{
memcpy(pTemp + k, arr + l, sizeof(int) * (mid - l + 1));
}
else//右边还没有放完
{
memcpy(pTemp + k, arr + right, sizeof(int) * (right - r + 1));
}
k += (right - r + 1);
#endif
//pTemp覆盖回arr中
memcpy(arr + left, pTemp, sizeof(int) * len);
//释放pTemp
delete[] pTemp;
}
void print(int* arr, int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}