整理归并排序

整理归并排序

二路归并

将两个有序表合并成一个有序表,称为二路归并。

合并两个有序序列

现在有两个单调上升序列,请将这两个序列合并为一个单调上升序列。

例如 a[7]={3,7,10,11,13,14,15} b[6]={2,4,8,9,10,12};

合并为c[13]={2,3,4,7,8,9,10,10,11,12,13}
步骤: 1. 设置两个变量,分别表示序列 a和序列b的下标 ,i表示序列a的下标,j表示序列b的下标,那么在取数时就可以是a[i]和b[j],把这两个元素进行比较,如果a[i]更小,那么将a[i]存入到c数组中,使用k表示存储的个数 k++,c[k]=a[i]; 否则,将b[j]存储到c数组中,k++,c[k]=b[j];直到a数组或者b数组存完为止。

2.此时会存在a数组或者b数组没有存完的情况,那么只需要将剩余的数据依次存入到c中即可。

复制代码
第一次  i=0  j=0   a[0]为3   b[0]为2   a[i]>b[j]   将b[j]存入到c[k]中  那么序列 c[13]={2};  j向后变化一次 j++.
第二次 i=0  j=1   a[0]为3   b[1]为4   a[i]<b[j]  将a[i]存入到c[k]中  那么 序列 c[13]={2,3}; i向后变化一次 i++.
第三次  i=1 j=1  a[1]为7  b[1]为4   a[i]>b[j]   将b[j]存入到c[k]中  那么序列 c[13]={2,3,4};  j向后变化一次 j++.
第四次 i=1 j=2 a[1]为7 b[2]为8  a[i]<b[j]  将a[i]存入到c[k]中  那么 序列 c[13]={2,3,4,7}; i向后变化一次 i++.
第五次  i=2 j=2 a[2]为10 b[2]为8   a[i]>b[j]   将b[j]存入到c[k]中  那么序列 c[13]={2,3,4,7,8};  j向后变化一次 j++.
第六次  i=2 j=3 a[2]为10 b[3]为9   a[i]>b[j]   将b[j]存入到c[k]中  那么序列 c[13]={2,3,4,7,8,9};  j向后变化一次 j++.
第七次  i=2 j=4 a[2]为10 b[4]为10   a[i]==b[j]  两数相等,优先存前面序列中的数据, 将a[i]存入到c[k]中  那么序列 c[13]={2,3,4,7,8,9,10};  i向后变化一次 i++.
第八次  i=3 j=4 a[3]为11 b[4]为10   a[i]>b[j]  将b[j]存入到c[k]中  那么序列 c[13]={2,3,4,7,8,9,10,10};  j向后变化一次 j++.
第九次  i=3 j=5 a[3]为11 b[5]为12   a[i]<b[j]  将a[i]存入到c[k]中  那么序列 c[13]={2,3,4,7,8,9,10,10,11};  i向后变化一次 i++.
第十次  i=4 j=5 a[3]为13 b[5]为12   a[i]>b[j]  将b[j]存入到c[k]中  那么序列 c[13]={2,3,4,7,8,9,10,10,11,12};  j向后变化一次 j++.    
此时b数组已经存储完毕,a数组还剩一个数据没有存储
那么把a数组中剩余的数据全部存储到c数组中,那么c[13]={2,3,4,7,8,9,10,10,11,12,13,14,15};

代码如下:

C++ 复制代码
//假设a序列有n个数,b序列有m个数
//本段代码以下标0开始
i=0;j=0;
while(i<n&& j<m){
	if(a[i]<b[j]){
		c[k]=a[i];
		k++;
		i++;
	}else{
		c[k]=b[j];
		k++;
		j++;
	}
}
//如果a数组中还有数
while(i<n)
{
	c[k]=a[i];
	k++;
	i++;
}
//如果b数组中还有数
while(j<m)
{
	c[k]=b[j];
	k++;
	j++;
}
//最终存储了k个数在数组c中,可以从0到k-1遍历数组c

归并排序

归并排序就是在二路归并的基础进行的。原理是将原来的无须序列一步一步拆分成一个个的元素。可以把这一个个元素看成一个单独的有序序列,之后再将每两个序列进行二路归并,逐步合成为一个序列的过程。

例如:无序序列 a[7]={3,1,4,7,2,5,6};

第一次可以分解为 {3,1,4,7} {2,5,6}

第二次可以分解为 {3,1} {4,7} {2,5} {6}

第三次可以分解为 {3} {1} {4} {7} {2} {5} {6}

然后两两进行归并

第一次归并:分别将1和2 3和4 5和6 进行二路归并

结果为 {1,3} {4,7} {2,5} {6}

第二次归并分别将1和2 3和4进行二路归并

结果为{1,3,4,7} {2,5,6}

第三次将1和2进行二路归并

结果为{1,2,3,4,5,6,7}

代码如下:

C++ 复制代码
//本段代码以下标1开始
void merge(int l,int r) {
	if(l>=r) return;
	int mid=(l+r)/2;
	merge(l,mid);
	merge(mid+1,r);
	int i=l,j=mid+1,k=0;
	while(i<=mid && j<=r) {  //以两段有序序列的大小依次存放到b数组(从小到大)
		if(a[i]>a[j]) { 
			b[++k]=a[j++];//更小的数放在前面
		} else {
			b[++k]=a[i++];
		}
	}
	while(i<=mid) {  //如果第一段序列没有排序完毕,继续存到 b
		b[++k]=a[i++];
	}
	while(j<=r) {//如果第二段序列没有排序完毕,继续存到b
		b[++k]=a[j++];
	}
	for(int i=l; i<=r; i++) {//更新a数组
		a[i]=b[i-l+1];
	}
}

如果习惯于从下标1开始,请私信博主,会对部分内容进行更改哦!

相关推荐
牛三金7 小时前
匿踪查询沿革-Private Information Retrieval(PIR)
算法·安全
德育处主任7 小时前
『NAS』在群晖部署一个文件加密工具-hat.sh
前端·算法·docker
星辞树7 小时前
从 L1/L2 到 Dropout:深度解析正则化,为何推荐系统“只能练一次”?
算法
玖剹8 小时前
队列+宽搜(bfs)
数据结构·c++·算法·leetcode·宽度优先
oioihoii8 小时前
构建高并发AI服务网关:C++与gRPC的工程实践
开发语言·c++·人工智能
mit6.8248 小时前
01bfs|前缀和的前缀和
算法
wen__xvn8 小时前
代码随想录算法训练营DAY11第五章 栈与队列part02
算法
春日见8 小时前
控制算法:PP(纯跟踪)算法
linux·人工智能·驱动开发·算法·机器学习