C++ std::list的merge()使用方式与分析

 更新时间:2024年04月23日 10:35:00   作者:Jane_Yih  
这篇文章主要介绍了C++ std::list的merge()使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

看到《C++标准库第2版》对list::merge()的相关介绍,令我有点迷糊,特意敲代码验了一下不同情况的调用结果。

《C++标准库第2版》对list::merge()的相关介绍

list::merge()定义

merge()的作用就是将两个list合并在一起,函数有2个版本:

c1.merge(c2)------------->这个版本含糊,将c2合入c1中,但合并后元素是怎么排序的呢?下文主要分析这个版本的不同调用结果

c1.merge(c2, op)--------->这个版本比较简单,就是将c2的内容合入到c1中,然后按op()排序

c1.merge(c2)调用情况分析

前提:有两个list,内容分别如下:

情况一:c1默认排序,c2不排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };
	list<int> c2{ 10,11,99,13,14,15 };
	cout << "-----------原始数据-----------" << endl;
	myPrinter(c1, c2);
 
	cout << "-----------排序后数据-----------" << endl;
	c1.sort(); //默认升序排序
	myPrinter(c1, c2);
 
	cout << "-----------合并后数据-----------" << endl;
	c1.merge(c2);
	myPrinter(c1, c2);

结果:合并后没有按c1的默认升序排序

情况二:c1不排序,c2默认排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };
	list<int> c2{ 10,11,99,13,14,15 };
	cout << "-----------原始数据-----------" << endl;
	myPrinter(c1, c2);
 
	cout << "-----------排序后数据-----------" << endl;
	c2.sort(); //默认升序排序
	myPrinter(c1, c2);
 
	cout << "-----------合并后数据-----------" << endl;
	c1.merge(c2);
	myPrinter(c1, c2);

结果:合并后没有按c2的默认升序排序

情况三:c1默认排序,c2默认排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };
	list<int> c2{ 10,11,99,13,14,15 };
	cout << "-----------原始数据-----------" << endl;
	myPrinter(c1, c2);
 
	cout << "-----------排序后数据-----------" << endl;
	c1.sort(); //默认升序排序
	c2.sort(); //默认升序排序
	myPrinter(c1, c2);
 
	cout << "-----------合并后数据-----------" << endl;
	c1.merge(c2);
	myPrinter(c1, c2);

结果:合并后也能按默认升序排序

情况四:c1默认排序,将c1赋值给c2,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };
	list<int> c2{ 10,11,99,13,14,15 };
	cout << "-----------原始数据-----------" << endl;
	myPrinter(c1, c2);
 
	cout << "-----------排序后数据-----------" << endl;
	c1.sort(); //默认升序排序
	c2 = c1;
	myPrinter(c1, c2);
 
	cout << "-----------合并后数据-----------" << endl;
	c1.merge(c2);
	myPrinter(c1, c2);

结果:可以看到,c1赋值给c2,使得c2也具有了与c1一样的默认排序,两者合并后,仍能按默认升序排序,结果与情况三结果相似。

下面使用自定义的降序规则(op())来排序

    //降序比较
	auto op = [](int first, int second) {
		return first > second;
	};

情况五:c1自定义降序排序,c2不排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };
	list<int> c2{ 10,11,99,13,14,15 };
	cout << "-----------原始数据-----------" << endl;
	myPrinter(c1, c2);
 
	cout << "-----------排序后数据-----------" << endl;
	c1.sort(op);
	myPrinter(c1, c2);
 
	cout << "-----------合并后数据-----------" << endl;
	c1.merge(c2);
	myPrinter(c1, c2);

结果:合并后没有按c1的自定义降序排序,与情况一相似

情况六:c1不排序,c2自定义降序排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };
	list<int> c2{ 10,11,99,13,14,15 };
	cout << "-----------原始数据-----------" << endl;
	myPrinter(c1, c2);
 
	cout << "-----------排序后数据-----------" << endl;
	c2.sort(op);
	myPrinter(c1, c2);
 
	cout << "-----------合并后数据-----------" << endl;
	c1.merge(c2);
	myPrinter(c1, c2);

结果:合并后没有按c2的自定义降序排序,与情况二相似

情况七:c1自定义降序排序,c2自定义降序排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };
	list<int> c2{ 10,11,99,13,14,15 };
	cout << "-----------原始数据-----------" << endl;
	myPrinter(c1, c2);
 
	cout << "-----------排序后数据-----------" << endl;
	c1.sort(op);
	c2.sort(op);
	myPrinter(c1, c2);
 
	cout << "-----------合并后数据-----------" << endl;
	c1.merge(c2);
	myPrinter(c1, c2);

结果:合并后,其结果仅仅是将c2放到了c1的末端,c1段、c2段数据仍是合并前的顺序,这与情况三有差异

情况八:c1自定义降序排序,c2默认排序,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };
	list<int> c2{ 10,11,99,13,14,15 };
	cout << "-----------原始数据-----------" << endl;
	myPrinter(c1, c2);
 
	cout << "-----------排序后数据-----------" << endl;
	c1.sort(op);
	c2.sort();
	myPrinter(c1, c2);
 
	cout << "-----------合并后数据-----------" << endl;
	c1.merge(c2);
	myPrinter(c1, c2);

结果:合并后,没有按c1的自定义降序排序,也没有按c2的默认排序,与情况二相似

情况九:c1自定义降序排序,将c1赋值给c2,c2合入c1中

	list<int> c1{ 0,1,2,88,3,4 };
	list<int> c2{ 10,11,99,13,14,15 };
	cout << "-----------原始数据-----------" << endl;
	myPrinter(c1, c2);
 
	cout << "-----------排序后数据-----------" << endl;
	c1.sort(op);
	c2 = c1;
	myPrinter(c1, c2);
 
	cout << "-----------合并后数据-----------" << endl;
	c1.merge(c2);
	myPrinter(c1, c2);

 

结果:合并后,其结果仅仅是将c2放到了c1的末端,c1段、c2段数据仍是合并前的顺序,这与情况七相同,但与情况三有差异

结论

因为合并后的顺序情况多变,所以如果希望合并后结果按某种规则排序,建议使用c1.merge(c2, op),指明合并后的排序规则。

当然,如果c1,c2都是默认排序,则可以直接使用c1.merge(c2),即上文提到的情况三。

附:示例的辅助函数

template <class T>
void printfList(const T& _Container, const char* _Delim)
{
	std::copy(_Container.cbegin(), _Container.cend(), std::ostream_iterator<T::value_type>(cout, _Delim));
	cout << endl;
}
 
void myPrinter(const list<int>& c1, const list<int>& c2)
{
	cout << "c1:";
	printfList(c1, " ");
	cout << "c2:";
	printfList(c2, " ");
	cout << "----------------------" << endl << endl;
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C语言新手初阶教程之三子棋实现

    C语言新手初阶教程之三子棋实现

    相信大家在小时候都用纸和笔与小伙伴们玩过一个经典的游戏之井字棋,即三子棋,下面这篇文章主要给大家介绍了关于C语言新手初阶教程之三子棋实现的相关资料,需要的朋友可以参考下
    2022-01-01
  • C/C++中OpenCV 矩阵运算的实现

    C/C++中OpenCV 矩阵运算的实现

    本文主要介绍了C/C++中OpenCV 矩阵运算的实现,包括基本算术运算(标量与矩阵)、矩阵乘法、转置、逆矩阵、行列式、迹、范数等操作,感兴趣的可以了解一下
    2025-05-05
  • 详解C语言之文件操作(上)

    详解C语言之文件操作(上)

    这篇文章主要介绍了关于C语言文件操作方法的相关资料,小编觉得这篇文章写的还不错,需要的朋友可以参考下,希望能够给你带来帮助
    2021-11-11
  • Matlab实现将图像序列合并为视频的方法详解

    Matlab实现将图像序列合并为视频的方法详解

    MATLAB是一种高性能语言,用于操纵矩阵、执行技术计算、绘图等。它代表矩阵实验室。借助这个软件,我们可以从图像中创建视频。这篇文章主要介绍了Matlab实现将图像序列合并为视频的四个方法,希望对大家有所帮助
    2023-03-03
  • 从入门到精通C++11 <chrono> 库特性

    从入门到精通C++11 <chrono> 库特性

    chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念,感兴趣的朋友一起看看吧
    2025-06-06
  • Linux下C语言的几道经典面试题小结(分享)

    Linux下C语言的几道经典面试题小结(分享)

    下面小编就为大家带来一篇Linux下C语言的几道经典面试题小结(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • C++超详细讲解引用和指针

    C++超详细讲解引用和指针

    引用是C++一个很重要的特性,顾名思义是某一个变量或对象的别名,对引用的操作与对其所绑定的变量或对象的操作完全等价,这篇文章主要给大家总结介绍了C++中引用的相关知识点,需要的朋友可以参考下
    2022-06-06
  • C++的类型转换(强转)你了解吗

    C++的类型转换(强转)你了解吗

    这篇文章主要为大家详细介绍了C++的类型转换,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • c语言中用字符串数组显示菜单的解决方法

    c语言中用字符串数组显示菜单的解决方法

    本篇文章是对c语言中用字符串数组显示菜单的方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C语言 数据类型详细介绍

    C语言 数据类型详细介绍

    本文主要讲解C语言 数据类型,这里整理了详细的数据类型的资料,希望能帮助刚刚开始学习C语言的同学
    2016-08-08

最新评论