归并排序
- 归并排序递归写法
- 一. 基本概念
- 二. 图解
归并排序递归写法
一. 基本概念
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
说了那么一大堆的话 其实中心思想就两个字 分治
二. 图解
我们要将整个数组有序就是要将它的左右数组都变得有序
我们要想将左右数组都变得有序就是要将它左数组的左右数组和右数组的左右数组变得有序
依次套娃
到最后面呢
会变成一个个单个的元素 这个时候肯定是有序了嘛
当它变成有序之后我们再一个一个的归
我们来看代码
// 创建一个临时的数组
int* tmp = (int*)malloc(sizeof(int) * (right + 1));
if (tmp==NULL)
{
printf("mergesort malloc error");
exit(-1);
}
这里我们首先要创建一个临时的数组来归并存贮数据 不然的话再内部排序会打乱顺序
之后我们开始考虑递归的问题
void _mergesort(int* arr, int left, int right,int* tmp)
{
// assert
assert(arr);
// 限制条件
if (left>=right)
{
return;
}
// 开始递归
int mid = (left + right) / 2;
_mergesort(arr, left, mid,tmp);
_mergesort(arr, mid+1, right,tmp);
我们先来看这一段
这里开始递归如果没有达到边界条件的话 (只有一个元素)
就往左和右继续走
递完毕了之后我们开始归
这里注意看图
// 开始归
int end1 = left;
int end2 = mid + 1;
int i = left;
// 开始将两个子数组中的内容 归并到tmp数组中
while (end1<=mid && end2<=right)
{
if (arr[end1]<arr[end2])
{
tmp[i++] = arr[end1++];
}
else
{
tmp[i++] = arr[end2++];
}
}
while (end1<=mid)
{
tmp[i++] = arr[end1++];
}
while (end2<=right)
{
tmp[i++] = arr[end2++];
}
// tmp数组里面被放满了 排序好的值
// tmp里面的值 全部赋值到arr里面了
for ( i = 0; i < right+1; i++)
{
arr[i] = tmp[i];
}
}
再之后我们将临时数组里面的值一一放到arr里面就好啦
这里有一点要注意的是i的赋值
这里的i要赋值left才可以
因为我们我们每次归的范围不同
当时这里写过了debug了很久