参考《算法竞赛入门经典》
时间复杂度:递归方程T(n)=2T(n/2)+o(n),T(1)=1 的解为T(n)=o(nlogn)
1.思想:分治思想,把序列分成尽量相等的两半;把两半元素分别排序;将两个有序表合并成一个。
关键部分:合并过程用类似解答树来理解分治思想的递归过程
#include<stdio.h>
#define MAX 20
void merge_sort(int *A,int x,int y,int *T)
{
if(y-x>1)//递归终结的条件
{
int m=x+(y-x)/2;
int p=x,q=m,i=x;
merge_sort(A,x,m,T);//前半部分递归
merge_sort(A,m,y,T);//后半部分递归
while(p<m||q<y) //只要有一个序列不为空,就要继续合并,因为有序列为空的情况,所以不能直接比较A[p],A[q]
{
if(q>=y||(p<m&&A[p]<=A[q]))//1.若第二个序列为空(由上一条件可知第一个序列一定不为空)复制A[p];
T[i++]=A[p++]; //2.否则,第二个序列不为空,当且仅当第一个序列也不为空,且A[p]<=A[q],复制A[p]
else
T[i++]=A[q++];
}
for(i=x;i<y;i++)
A[i]=T[i];
}
}
int main()
{
int A[8]={13,7,2,20,9,11,1,12};
int T[MAX];
int i;
merge_sort(A,0,8,T);
for(i=0;i<8;i++)
printf("%d ",A[i]);
printf("\n");
return 0;
}
2. 理解短路运算符的巧妙用法: 条件1满足,就不会计算条件2;条件1不满足,就一定会计算条件2。