归并排序(八大排序之一):应该是八大排序里面代码最长的了,但是理解起来并不难,加油吧!
1.MergerSort.cpp(里面也包括主函数)
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//归并排序:时间O(nlogn) 空间:O(n) 稳定性:稳定
void Merger(int* arr, int len, int gap)
{
//gap是归并段的长度
int low1 = 0;//第一个归并段的起始下标
int high1 = low1 + gap - 1;第一个归并段的结束下标
int low2 = high1 + 1;第二个归并段的起始下标
int high2 = low2 + gap < len ? low2+gap - 1 : len - 1;//第二个归并段的结束下标 要判断不能在数字不够的情况下越界
int* brr = (int*)malloc(len * sizeof(int));//申请内存
assert(brr != NULL);
int i = 0;//brr的下标
//1.有两个归并段
while (low2 < len)
{
//(1)有两个归并段且都有数据 ps:永远用low1和low2比
while (low1 <= high1 && low2 <= high2)
{
if (arr[low1] <= arr[low2])
{
brr[i++] = arr[low1++];//小的在前面先放入brr中
}
else
{
brr[i++] = arr[low2++];
}
}
//(2)一个归并段的数据已经完成了,另一个还有数据
while (low1 <= high1)
{
brr[i++] = arr[low1++];
}
while (low2 <= high2)
{
brr[i++] = arr[low2++];
}
//(3)接下来的两个归并段
low1 = high2 + 1;
high1 = low1 + gap - 1;
low2 = high1 + 1;
high2 = low2 + gap < len ? low2 + gap - 1 : len - 1;
}
//2.只有一个归并段
while (low1 < len)
{
brr[i++] = arr[low1++];
}
//3.arr中的数据拷贝到brr中
for (i = 0; i < len; i++)
{
arr[i] = brr[i];
}
//4.free掉brr ***容易忘
free(brr);
}
void MergerSort(int* arr, int len)
{
for (int i = 1; i < len; i*=2)
{
Merger(arr, len, i);//一次归并O(n)
}
}
void Show(int* arr, int len)
{
for (int i = 0; i < len; i++)
{
printf("%3d", arr[i]);
}
printf("\n");
}
int main()
{
int arr[6] = { 7,9,3,-4,5,6 };
MergerSort(arr, 6);
Show(arr, 6);
}
2.运行截图: