整理归并排序

整理归并排序

二路归并

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

合并两个有序序列

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

例如 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 分钟前
vector模拟实现
c++
本喵是FW13 分钟前
C语言手记1
java·c语言·算法
咱就是说不配啊18 分钟前
3.19打卡day33
数据结构·c++·算法
2501_9249526921 分钟前
嵌入式C++电源管理
开发语言·c++·算法
2401_8426236527 分钟前
C++中的访问者模式高级应用
开发语言·c++·算法
森林里的程序猿猿37 分钟前
垃圾收集器G1和ZGC
java·jvm·算法
机器学习之心1 小时前
LSBoost增强算法回归预测+SHAP可解释分析+新数据预测(多输入单输出)MATLAB代码
算法·matlab·回归·lsboost·shap可解释分析
AI-Ming1 小时前
注意力机制
算法·ai·ai编程
favour_you___1 小时前
C++实现的高性能内存池项目
c++
ℳ๓₯㎕.空城旧梦1 小时前
C++中的解释器模式
开发语言·c++·算法