算法导论之归并排序
此算法的介绍多如牛毛,我就不解释了。
相信算法导论中分治归并的思想不难理解,主要是几个细节需要注意一下。
- 数组作为参数的传递:
在本程序中,用到了对数组的引用:*P 。*p意为指针P所指的数据。而在形参中的Arry实为数组Arry的地址。于是*p就成了Arry的地址所指向的数据。对Arry的地址所指向的数据进行改变,就是改变Arry数组本身的数据。它与将int Arry[]作为形参的区别是,后者是将Arry的数据复制到形参int Arry[]中,对其进行改变,只能改变形参数组的数据,而不能正真对Arry[]的数据进行改变。 内存申请
本程序中用到了一个很小众的函数malloc,具体用法是:int * L=(int*)malloc(sizeof(int)*(n1+2));//分配大小为n1+2个int字节的连续内存
百度一下便可深度了解,不做介绍。分离条件与程度
把每一个数字都分开才能利用归并排序获得正确的结果这里的代码肯定是比较经典易懂的
先输入N个数字(小于500),然后对后面输入的N个数字排序
#include<cstdio>
#include<stdlib.h>
#define INF 500
void MERGE(int *Arry,int beg,int mid,int endd)
{
int n1=mid-beg+1,n2=endd-mid;
int *L=(int*)malloc(sizeof(int)*(n1+2));//分配大小为n1个int字节的连续内存
int *R=(int*)malloc(sizeof(int)*(n2+2));
int i=1,j=1;
for(i=1;i<=n1;i++) L[i]=Arry[beg+i-1];
for(j=1;j<=n2;j++) R[j]=Arry[mid+j];
L[n1+1]=INF;R[n2+1]=INF;
i=1,j=1;
for(int k=beg;k<=endd;k++)
{
if(L[i]<=R[j]) Arry[k]=L[i++];
else Arry[k]=R[j++];
}
printf("hhhhh\n");
free(L);free(R);
}
void MERGE_SORT(int *Arry,int head,int tail)
{
if(head<tail)//这个条件是非常重要的,必须把所有的元素都分开才能正确地排序
{
int midd=(head+tail)/2;
MERGE_SORT(Arry,head,midd);
MERGE_SORT(Arry,midd+1,tail);
MERGE(Arry,head,midd,tail);
}
}
int main()
{
int N,kase;
scanf("%d",&N);
int *Arry=(int*)malloc(sizeof(int)*(N+1));
for(int h=1;h<=N;h++)
{
scanf("%d",&kase);
Arry[h]=kase;
}
MERGE_SORT(Arry,1,N);
for(int s=1;s<=N;s++) printf("%d ",Arry[s]);
printf("\n");
return 0;
}
好辣!归并排序比插入排序难多了,不要灰心,慢慢看,我的程序应该是非常符合大众口味了~