小白一天学一个算法系列,从逻辑、关键、算法动画、完整示例代码四个方面进行学习。
(注:冒泡排序示例代码有更详细的注解,共用代码后续算法示例代码中不再注释。)
以下示例是两两排序,又称二路归并,也可以三路、N路,二路归并实现较简单。归并排序适用于多机同时排序。
逻辑:先让子序列都有序,再让子序列之间有序。
关键:先分后排序,合并两个有序数列。
静态过程:
完整示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 10
typedef int ElemType;
//数组打印
void arr_print(int* arr)
{
int i;
for(i=0;i<N;i++)
{
printf("%3d",arr[i]);
}
printf("\n");
}
//归并排序:比较大小,两两合并
void sort_merge(ElemType A[],int low,int mid,int high)
{
ElemType B[N]; //存放数组A的元素
int i,j,k;
for(i=low;i<=high;i++)
{
B[i]=A[i]; //复制A的元素给B
}
for(i=low,j=mid+1,k=i;i<=mid&&j<=high;k++)
{
if (B[i]<=B[j]) //前半部分的元素大于后半部分的元素时
{
A[k]=B[i++]; //B中前半部分的元素重新填入到数组A中,并且游标i++
}else
{
A[k]=B[j++];
}
}
//有序数组还有元素时,两个条件有一个不为真时跳出for循环
while (i<=mid)
{
A[k++]=B[i++];
}
while (j<=high)
{
A[k++]=B[j++];
}
}
//归并排序:分割数组,递归合并
void recur_merge(ElemType A[],int low, int high)
{
if (low<high) //low=high时为一个元素,自然有序
{
int mid=(low+high)/2;
recur_merge(A,low,mid); //难点:先递归二分
recur_merge(A,mid+1,high);
sort_merge(A,low,mid,high); //难点:再排序合并
}
}
int main()
{
int i;
int arr[N];
srand((unsigned int)time(NULL));
for(i=0;i<N;i++)
{
arr[i]=rand()%100;
}
printf("随机数生成:\n");
arr_print(arr);
printf("归并排序结果:\n");
recur_merge(arr,0,N-1); //注意传入的第三个参数是最后一个元素的下标
arr_print(arr);
system("pause");
return 0;
}