版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CSDN___CSDN/article/details/83471804
许多有用的算法在结构上是递归的:为了解决一个给定的问题,算法一次或多次递归地调用其自身以解决紧密相关地若干子问题。这些算法典型的遵循分治法地思想:将原问题分解成几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后再合并这些子问题的解来建立原问题的解。
分治模式在每层递归时都有三个步骤:
- 分解原问题为若干子问题,这些子问题是原问题规模较小的实例。
- 解决这些子问题,递归地求解各子问题。若子问题规模足够小,则直接求解。
- 合并这些子问题的解成原问题的解。
归并排序:完全遵循分治模式。
- 分解:分解该待排序的n个元素的序列成各具n/2元素的两个子序列。
- 解决:使用归并排序递归地解决两个子序列。
- 合并:合并两个已排序的子序列以产生以排序的答案。
归并排序示意图:
归并排序C语言代码实现:
从大到小的排序:
//归并排序
#include "stdio.h"
#include "math.h"
#include "time.h"
#include "stdlib.h"
#define MAXSIZE 1000
#define INF -100000
int array[MAXSIZE];
int start,finish;
int main ()
{
start=clock();
int len;
void merge_sort(int array[],int p,int r);
void merge(int array[],int p,int q,int r);
printf("输入数组元素个数:\n");
scanf("%d",&len);
for(int i=1;i<=len;i++)
{
array[i]=(rand()%10000);
}
printf("排序前:\n");
for(int i=1;i<=len;i++)
{
printf("%d ",array[i]);
}
merge_sort(array,1,len);
printf("\n排序后结果为:\n");
for(int i=1;i<=len;i++)
{
printf("%d ",array[i]);
}
finish=clock();
printf("\nRunning Time:%d s",(finish-start)/CLOCKS_PER_SEC);
return 0;
}
void merge(int array[],int p,int q,int r)
{
int n1=q-p+1,n2=r-q,i,j,k;
int L[n1+2],R[n2+2];
L[0]=-1;
for(i=1;i<=n1;i++)
{
L[i]=array[p+i-1];
}
L[n1+1]=INF;
R[0]=-1;
for(j=1;j<=n2;j++)
{
R[j]=array[q+j];
}
R[n2+1]=INF;
i=1;j=1;
for(k=p;k<=r;k++)
{
if(L[i]>=R[j])
{
array[k]=L[i];
i++;
}
else
{
array[k]=R[j];
j++;
}
}
}
void merge_sort(int array[],int p,int r)
{
if(p<r)
{
int q=(p+r)/2;
merge_sort(array,p,q);
merge_sort(array,q+1,r);
merge(array,p,q,r);
}
else
{
return ;
}
}
从小到大的排序:
//归并排序
#include "stdio.h"
#include "math.h"
#include "time.h"
#include "stdlib.h"
#define MAXSIZE 1000
#define INF 100000
int array[MAXSIZE];
int start,finish;
int main ()
{
start=clock();
int len;
void merge_sort(int array[],int p,int r);
void merge(int array[],int p,int q,int r);
printf("输入数组元素个数:\n");
scanf("%d",&len);
for(int i=1;i<=len;i++)
{
array[i]=(rand()%10000);
}
printf("排序前:\n");
for(int i=1;i<=len;i++)
{
printf("%d ",array[i]);
}
merge_sort(array,1,len);
printf("\n排序后结果为:\n");
for(int i=1;i<=len;i++)
{
printf("%d ",array[i]);
}
finish=clock();
printf("\nRunning Time:%d s",(finish-start)/CLOCKS_PER_SEC);
return 0;
}
void merge(int array[],int p,int q,int r)
{
int n1=q-p+1,n2=r-q,i,j,k;
int L[n1+2],R[n2+2];
L[0]=-1;
for(i=1;i<=n1;i++)
{
L[i]=array[p+i-1];
}
L[n1+1]=INF;
R[0]=-1;
for(j=1;j<=n2;j++)
{
R[j]=array[q+j];
}
R[n2+1]=INF;
i=1;j=1;
for(k=p;k<=r;k++)
{
if(L[i]<=R[j])
{
array[k]=L[i];
i++;
}
else
{
array[k]=R[j];
j++;
}
}
}
void merge_sort(int array[],int p,int r)
{
if(p<r)
{
int q=(p+r)/2;
merge_sort(array,p,q);
merge_sort(array,q+1,r);
merge(array,p,q,r);
}
else
{
return ;
}
}