闲来无聊来说说归并排序
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;//范围扩大一倍
}
}
文字可能不太好理解,那我来给大家画几张图看看吧
首先我们随便给些数
然后我们开始给他们分成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;//范围扩大一倍
}
}
相关文章推荐
- 无聊时总结总结算法之06归并排序
- 操作系统三个简单的部分(Operating Systems in Three Easy Pieces闲来无聊,翻译的)虚拟化部分-原文编号4进程的概念
- 闲来无聊 随便说说
- 闲来无聊(一)怎样更改U盘或电脑磁盘的图标?
- 无聊写排序之 ---- 归并排序(MergeSort) 递归实现
- 闲来无聊做了一个批处理编辑工具!
- 打法一下时间_面试经典_没事笑笑_闲来无聊
- 闲来无聊 听几首歌 休息的时候
- HOT!闲来无聊,总结了下10个作为网民不得不知道的网址
- 闲来无聊,研究一下Web服务器 的源程序
- python路由跟踪(闲来无聊写着玩)
- 闲来无聊,研究一下Web服务器 的源程序
- 无聊写排序之 ---- 归并排序(MergeSort) 非递归实现
- 又一次闲来无聊,使用Java的动态代理机制来模拟AOP
- 闲来无聊编译了一下ffmpeg
- 闲来无聊,想了下秒杀、抢购实现方法
- 闲来无聊,玩玩JavaDB(Derby)
- 操作系统三个简单的部分(Operating Systems in Three Easy Pieces闲来无聊,翻译的)1,2(操作系统的介绍部分)
- 闲来无聊,自己写的itoa函数
- 又一次闲来无聊,使用Java的动态代理机制来模拟AOP