基本思想:
合并排序的递归方式是基于分治思想的一个实例,分治把一个复杂问题给分解成各个子问题,通过求解这些简单的子问题,最后合成各个子问题的解实现初始问题的求解;同样,合并算法把一个数组对半两个子数组,然后对两个子数组进行排序,递归调用排序过程;性能
- 最坏情况下时间复杂度:Θ(nlogn)
- 最好情况下时间复杂度:Θ(nlogn)
- 平均情况下时间复杂度:Θ(nlogn)
- 最坏情况下空间复杂度:Θ(n) 辅助
public static void mergeSort(int[] list,int[] array,int left,int mid,int right)
{
int k=left,//新array数组的初始化,即初始化下标
i=left,//list数组的下标
j=mid+1;
//将两个待排数组放入到新的数组中arra[],直到某一方的待排数组耗尽即可停止循环
while(i<=mid&&j<=right)//设定边界值。左边数组的下标小于等于最大长度mid
{
if(list[i]<=list[j])//左半部分进行比较
{
array[k++]=list[i++];
}
else //右半部分进行比较
{
array[k++]=list[j++];
}
}
// 考虑某个数组剩余数的情况
if(i>mid)//左指针已经大于中间点
{
//假如左边数组耗尽,说明右边数组还有剩余数
for(int t=j;t<=right;t++)
{
array[k++]=list[t];//继续把剩余数组放入新数组中
}
}
else
{
//假如右边数组耗尽,说明左边数组还有剩余数
for( int t=i;t<=mid;t++)
{
array[k++]=list[t];
}
}
}
public static void copy(int[] list,int[] array,int le,int r){
for(int i=le;i<=r;i++)
{
list[i]=array[i];
}
}
public static void digui(int[] list,int left,int right){
int[] b=new int[list.length];//创建一个新的数组b
if(left<right)
{
int mid=(left+right)/2;
digui(list,left,mid);//左边排序
digui(list,mid+1,right);//右边排序
mergeSort(list,b,left,mid,right);
copy(list,b,left,right);
}
}
分析:
合并排序将输入序列分成两部分并递归处理每一部分。当子问题解决后,算法又将子问题解合并。假设具有n个元素的合并排序的复杂度表示为T(n),则合并排序的递归式可定义为:
T(n)=2T(n/2)+Θ(n)
根据分治法注定理,有T(n)=Θ(nlogn)