归并我们可以同样套模版,首先找个边界1,这个边界我们就用MID。 然后我们把从MID开始分为两部分。
像这种情况,我们应该用MID=r+l+1/2,因为是偶数个:
所以我们的MID应该为(0+7+1/2=(8/2)=4
此刻我们就变形为如下这个样子了:
然后我们把R指针移动到MID+1的位置,然后和L指针进行比较,谁小谁就放到temp里面:
4比9小1,放TEMP里面,然后L++,挪到5头上,K++,跳到下一个位置:
接着比较L和R,5比9小,5放K那里,++:
7比9小,挪动。 9小于等于9,再挪:
这个时候我们就发现问题了,左边都排完了,但是3却比前面的数都小,这就有问题了,所以我们一开始不能直接把MID拿过来放中间,我们可以把3放到右半部分的开头,让R=MID:
这样的话就可以先比较3和4的值,把3先排过去了。这样排完之后是这个样子:
这个时候我们发现右半部分还剩好多。那我们就把它跟x,也就是MID 3作对比,如果小于MID就放过去
但是,我们发现,放过去之后也不行,这个4显得有点突兀:
实际上,因为我们的前半部分刚好是一个有序的,所以才可以正常排,假设我们前半部分也是一个乱序的:
那么排完之后应该是:
这个结果明显不是我们需要的,假设我们的前半部分和后半部分都是有序的:
那么这样排完之后应该是:
这个结果才是我们想要的,所以我们应该对前半部分和后半部分先排序,具体的排序方法用递归:
归并排序——一文吃透归并和递归的思想和完整过程!(没看懂请留言) - 少年π - 博客园 (cnblogs.com)
总结,归并模版
先分治,再递归,后合并。
归并
#include<iostream>
using namespace std;
const int N=1e6+10;
int n=0;
int q[N];
int temp[N];
void G_qsort(int q[],int l,int r)
{
//递归结束条件
if(l>=r) return;
//首先确定主元
int mid=l+r>>1;
G_qsort(q,l,mid); //左区间排序
_qsort(q,mid+1,r); //右区间排序
int i=l,j=mid+1, k=0;
while(i<=mid && j<=r)//递归结束条件
//谁小谁往temp里面放
if(q[i]<=q[j]) temp[k++]=q[i++];
else temp[k++]=q[j++];
//如果有一个指针走完了,另一个指针还没走完,就把剩下的值也放到temp里
while(i<=mid) temp[k++]=q[i++];
while(j<=r) temp[k++]=q[j++];
for(int i=l,j=0;i<=r;i++,j++)
{
q[i]=temp[j];
}
//放回到q
// for(int i=0;i<r;i++)
// {
// q[i]=temp[i];
//}
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&q[i]);
}
G_qsort(q,0,n-1);
for(int i=0;i<n;i++)
{
printf("%d ",q[i]);
}
return 0;
}