归并排序
定义:将两个有序数组合并为一个有序数组。归并排序也叫合并排序。
如何使用归并排序算法对一个乱序数组进行排序呢?先拆分,再合并!
1、拆!将数组使用递归方式进行一分为二地拆分,直到拆到不能拆为止。
2、合!将拆分后的数组,每个元素都可以看做有序数组。将其逐步合并。
参考代码:
#include <stdio.h>
#include <stdlib.h>
// 第二步,合并!将两个排序好的数组进行合并为一个排序好的数组
void mergeArray(int* nums, int startIndex, int midIndex, int endIndex, int* tmpArray) {
int leftIndex = startIndex; // 左侧序列指针
int rightIndex = midIndex + 1; // 右侧序列指针
int tmpIndex = 0; // 临时数组的临时指针
if(startIndex == endIndex) {
return;
}
while (leftIndex <= midIndex && rightIndex <= endIndex) {
if (nums[leftIndex] <= nums[rightIndex]) {
tmpArray[tmpIndex] = nums[leftIndex];
leftIndex++;
} else {
tmpArray[tmpIndex] = nums[rightIndex];
rightIndex++;
}
tmpIndex++;
}
// 需要考虑这种情况:如果一侧数组已经被排序完成,另一侧数列不分元素还未排序,说明另一侧未排序的这部分元素比较大,直接追加到末尾即可。
while (leftIndex <= midIndex) {
tmpArray[tmpIndex++] = nums[leftIndex++];
}
while (rightIndex <= endIndex) {
tmpArray[tmpIndex++] = nums[rightIndex++];
}
// tmpArray数组当前已经是排序好的数组,要将tmpArray数组元素拷贝到nums数组中
tmpIndex = 0;
while (startIndex <= endIndex) {
nums[startIndex++] = tmpArray[tmpIndex++];
}
}
// 第一步,分割!先把数组分为两份,使用递归的方式分到不可再分为止
void splitArray(int* nums,int startIndex, int endIndex, int* tmp) {
if(startIndex < endIndex) {
int midIndex = (startIndex + endIndex) /2;
splitArray(nums,startIndex,midIndex,tmp);
splitArray(nums,midIndex+1,endIndex,tmp);
//将左右两个数组进行合并
mergeArray(nums,startIndex,midIndex,endIndex,tmp);
}
}
// 归并排序主函数
void mergeSortAlgorithm(int* nums,int numsSize) {
// 排序前,先创建临时数组,避免在排序中频繁申请内存空间
int* tmpArray = malloc(sizeof(int) * numsSize);
splitArray(nums,0,numsSize-1,tmpArray);
}
int main() {
printf("快速排序算法(Quick Sort Algorithm)\n");
int nums[] = {81, 94, 11, 96, 12, 35, 17, 95, 28, 58, 41, 75, 15};
printf("排序前:");
for (int i = 0; i < 13; ++i) {
printf("%d ",nums[i]);
}
mergeSortAlgorithm(nums, 13); // 要求传入start和end指针
printf("\n排序后:");
for (int i = 0; i < 13; ++i) {
printf("%d ",nums[i]);
}
return 0;
}