C++ STL merge/inplace_merge 归并函数简单使用

C++ STL merge/inplace_merge 归并函数简单使用

c++自带的归并函数也是比较好用的,可以节省很多时间,归并也分为异地归并和原地归并,先来看一下异地归并

异地归并

异地归并需要一个额外的空间来存储归并后的结果,通常是通过传递该空间的起始迭代器(最底层迭代器)来实现的

/*
function      : 将两个有序序列按照运算符归并为一个有序序列
param beign1  : 子序列1起始迭代器
param end1    : 子序列1结束迭代器
param beign2  : 子序列2起始迭代器
param end2    : 子序列2结束迭代器
param both    : 结果序列起始迭代器
param compare : 比较运算符,默认是小于,也就是升序归并
*/
merge(begin1, end1, begin2, end2, both, compare);

示例1.1

在这里插入图片描述

vector<int> seq1 = {1,3,5,7};
vector<int> seq2 = {2,4,6,8};
vector<int> merge_seq(8);

merge(seq1.begin(), seq1.end(), seq2.begin(), seq2.end(), merge_seq.begin());

for(int i=0; i<merge_seq.size(); i++) 
	cout<<merge_seq[i]<<" ";
cout<<endl;

示例1.2

还可以通过修改比较运算符达到预期的效果
比如:以到原点的距离为大小比较
在这里插入图片描述

#define dist(x) ((int)fabs(x))
struct cmp
{
	bool operator() (int a, int b){return dist(a) < dist(b);}
};

vector<int> seq1 = {1,3,5,7};
vector<int> seq2 = {1,-3,-5,-7};
vector<int> merge_seq(8);

merge(seq1.begin(), seq1.end(), seq2.begin(), seq2.end(), merge_seq.begin(), cmp());

for(int i=0; i<merge_seq.size(); i++) 
	cout<<merge_seq[i]<<" ";
cout<<endl;

原地归并

原地归并不需要额外的空间,只需要指定分界点即可

/*
function      : 将一个两部分有序的数组归并到一个数组
param l_begin : 左子数组起始迭代器(也是整个数组的起始迭代器 
param r_begin : 右子数组起始迭代器
param end     : 整个数组结束迭代器
param compare : 比较运算符,默认是小于,也就是升序归并
*/
inplace_merge(l_begin, r_begin, end, compare); 

注意:
在STL中区间习惯是左闭右开,也就是说,假设两个有序的子序列下标是[0,3][4,7],那么分界点应该是4,即两个子区间应该是[0,4)[4,8)两个区间,传递参数的时候需要注意

如果记不住,可以这样传参:(起始迭代器,右半部分序列起始迭代器,结束迭代器)

示例 2.1

在这里插入图片描述

vector<int> seq = {1,3,5,7,2,4,6,8,9};
	
inplace_merge(seq.begin(), seq.begin()+4, seq.end());

for(int i=0; i<seq.size(); i++) 
	cout<<seq[i]<<" ";
cout<<endl;

示例2.2

同样可以通过自定义的比较函数来实现奇怪的功能,以【到原点距离】作为比较判据
在这里插入图片描述

#define dist(x) ((int)fabs(x))
struct cmp
{
	bool operator() (int a, int b){return dist(a) < dist(b);}
};

vector<int> seq = {1,3,5,7,-1,-3,-5,-7,-9};

inplace_merge(seq.begin(), seq.begin()+4, seq.end(), cmp());

for(int i=0; i<seq.size(); i++) 
	cout<<seq[i]<<" ";
cout<<endl;

附:原地归并实现归并排序(递归)

在这里插入图片描述
递归边界条件是数组长度为1,就不操作

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void merge_sort(vector<int>& nums, int l, int r)
{
	if(l<r)
	{
		int mid = (l+r)/2;
		merge_sort(nums, l, mid);
		merge_sort(nums, mid+1, r);
		inplace_merge(nums.begin()+l, nums.begin()+mid+1, nums.begin()+r+1);	
	}
}

int main()
{
	vector<int> nums{3,1,4,2,7,5,6,8,9};
	
	merge_sort(nums, 0, nums.size()-1);
	
	for(int i=0; i<nums.size(); i++) 
		cout<<nums[i]<<" ";
	cout<<endl;
	
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章