您的位置:首页 > 其它

闲来无聊来说说归并排序

2017-10-24 18:25 218 查看
说到归并排序,其实归并排序还是比较重要的,归并归并,就是先分后并,也就和分治法比较相似了,直切主题吧,我们来谈谈归并排序的基本思想,就是先将数组平均分为两部分,看其中两部分是否有序,若两部分都已经有序,则只需要把他两合并成一个新的数列即可,但要是两个数组还是无序的,我们就要再分,直到里面只有一个元素的时候或里面的元素已经有序。然后我们再将它们一步一步地合并起来。

文字可能不太好理解,那我来给大家画几张图看看吧

首先我们随便给些数

然后我们开始给他们分成2部分

发现各部分还是无序的,那我们就继续分

直到分到1个1个的,那么就每个里面就默认有序了,好了,既然有序了,那么我们就要合并了,那就合么。

合并完了,数列也就有序了。

接下来就用代码给大家讲讲吧,自己写了遍发现有些地方容易出错

void Merge(int *arr,int *brr,int start,int mid,int end)

{
int left=start;
int right=mid+1;
int tmpindex=start;
while(left !=mid+1&&right !=end+1)//把小的数放入到brr中
{
if(arr[left]>arr[right])
{
brr[tmpindex++]=arr[right++];
}
else
{
brr[tmpindex++]=arr[left++];
}
}
while(left !=mid+1)//这是左边可能没放完
{
brr[tmpindex++]=arr[left++];
}
while(right !=end+1)//这是右边可能没放完
{
brr[tmpindex++]=arr[right++];
}
for(int i=start;i<=end;i++)//把brr中的数再放回到arr中
{
arr[i]=brr[i];//注意这里是可以=end的
}

}

void MergeSort(int *arr,int *brr,int start,int end)

{
if(start<end)
{
int mid=(start+end)/2;
MergeSort(arr,brr,start,mid);//左边有序
MergeSort(arr,brr,mid+1,end);//右边有序
Merge(arr,brr,start,mid,end);//再合并
}

}

再分析一下这个程序,它是一个稳定的算法,时间复杂度是O(nlogn);

其实思路出来了,就很好实现了,但是我们用的是递归方法,但很多时候是让我们去写一个非递归,所以我们就再写一个非递归:

void New_MergeSort(int arr[],int brr[],int len)

{//非递归实现   

    int size=1,low,mid,high;

    while(size<=len-1)  

    {  

        low=0;  

        while(low+size<=len-1)  

        {  

            mid=low+size-1;  

            high=mid+size;  

            if(high>len-1)//第二个序列个数不足size   

                high=len-1;         

            Merge(arr,brr,low,mid,high);//调用归并子函数   

            low=high+1;//下一次归并时第一关序列的下界   

        }  

        size*=2;//范围扩大一倍   

    }  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: