归并排序所采用的思想是分治法,即:分解 ->解决->合并
假设面对一个无序的数组,如{5, 19, 6, 97, 12, 53, 12, 21, 47, 10},将其分解为左右两个数组,但此时这两个数组还是无序的,因此,还需要进一步的分解,经过若干步之后,分解后如下所示
{{5}, {19}, {6}, {97}, {12}, {53}, {12}, {21}, {47}, {10}
当每个数组中仅有一个元素的,可以认为此数组是有序的,接下来,这些数组两两合并,最后一个组合成一个完整的有序数组
/**
array数组中,left到mid和mid+1到right的部分都是已经排序好的,该函数的作用是将其重新排列为顺序数组
@param array 需要排序的数组
@param left 左边坐标
@param mid 中间坐标
@param right 右边坐标
*/
void Merges (int *array, int left, int mid, int right)
{
//TODO 1.获取左右两侧的长度
int leftNum = mid - left;
int rightNum = right - mid - 1;
//TODO 2.创建两个数组来保存左右两边的数据,数组长度为上面获取的长度加1
int leftArray[mid - left + 2];
int rightArray[right - mid + 1];
//TODO 3.从array中取出数据放入左右两个数组中
for (int i = 0; i <= leftNum; i++)
leftArray[i] = array[left + i];
for (int i = 0; i <= rightNum; i++)
rightArray[i] = array[mid + 1 + i];
//TODO 4.两个数组的最后一位设置为最大数
leftArray[leftNum + 1] = INT_MAX;
rightArray[rightNum + 1] = INT_MAX;
//TODO 5.添加索引
int leftIndex = 0;
int rightIndex = 0;
//TODO 6.将左右数组中的数进行比较后重新放入array中,哪一个数组大,则该数组的索引加1
for (int i = left; i <= right; i++) {
if (leftArray[leftIndex] < rightArray[rightIndex]) {
array[i] = leftArray[leftIndex];
leftIndex++;
}
else {
array[i] = rightArray[rightIndex];
rightIndex++;
}
}
}
/**
该函数的作用是分解一个数组
@param array 需要分解的数组
@param left 左边坐标
@param right 右边坐标
*/
void Mergesort (int *array, int left, int right)
{
//TODO 1.只有当left小于right时才可以进行下一步
if (left < right)
{
//TODO 2.获取中点
int mid = (left + right) / 2;
//TODO 3.继续分解,知道每个数组中仅有一个元素位置,此时默认该数组为有序的,才可以进行合并
Mergesort(array, left, mid);
Mergesort(array, mid + 1, right);
//TODO 4.将两个有序的数组合并
Merges(array, left, mid, right);
}
}