STL容器之list
【1】list简介
实质上,list容器就是一个双向链表,可以高效地进行插入、删除操作。
【2】list链表常用方法
(1)构造、赋值、清空、删除、插入、判空等
应用示例代码如下:
#include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1; // 构造函数(构建一个list,有10个元素,每个元素值都是10)
list<int> myList2(, );
print(myList2); // 拷贝构造函数
list<int> myList3(myList2);
print(myList3); // 由区间内的值初始化list
int nArrayA[] = {, , , , };
list<int> myList4(nArrayA, nArrayA + );
print(myList4); // 赋值assign(input_iterator start, input_iterator end);
myList1.assign(nArrayA, nArrayA + );
print(myList1); // 赋值assign(size_type num, const Type & val);
myList1.assign(, );
print(myList1); // 返回对最后一个元素的引用
cout << myList4.back() << endl; // 返回对第一个元素的引用
cout << myList4.front() << endl; // 清空链表clear
myList4.clear();
cout << myList4.empty() << endl; // 删除元素erase(iterator pos)
list<int>::iterator iter = myList1.begin();
for (; iter != myList1.end(); )
{
myList1.erase(iter++);
}
cout << myList1.empty() << endl; // 删除元素erase(iterator start, iterator end)
myList3.erase(myList3.begin(), myList3.end());
cout << myList3.empty() << endl; // 插入元素insert(iterator pos, const TYPE& val)
myList1.insert(myList1.begin(), );
print(myList1); // 插入元素insert(iterator pos, size_type num, const TYPE &val)
myList1.insert(myList1.begin(), , );
print(myList1); // 插入元素insert(iterator pos, input_iterator start, input_iterator end)
int nArrayB[] = {, , , };
myList1.insert(myList1.begin(), nArrayB, nArrayB + );
print(myList1); system("pause");
} // run out:
/*
10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10
10 20 30 40 50
10 20 30 40
100 100 100 100 100 100 100 100 100 100
50
10
1
1
1
110
23 23 23 23 23 23 23 23 23 23 110
7 8 9 10 23 23 23 23 23 23 23 23 23 23 110
请按任意键继续. . .
*/
(2)merge方法
请看如下最常见的崩溃代码:
代码1:链表1无序,链表2无序。
#include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1, myList2;
// 赋值
myList1.assign(, );
// 插入元素
int nArrayA[] = {, , , , };
myList1.insert(myList1.begin(), nArrayA, nArrayA + );
// 追加元素
for (int i = ; i < ; ++i)
{
myList1.push_back(i + );
}
cout << "打印链表1的数据:" << endl;
print(myList1); myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
cout << "打印链表2的数据:" << endl; print(myList2); myList1.merge(myList2);
cout << "合并后,打印链表1的数据:" << endl;
print(myList1);
cout << "合并后,打印链表2的数据:" << endl;
print(myList2); system("pause");
}
运行结果如下图:
代码2:链表1无序,链表2升序。
#include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1, myList2;
// 赋值
myList1.assign(, );
// 插入元素
int nArrayA[] = {, , , , };
myList1.insert(myList1.begin(), nArrayA, nArrayA + );
// 追加元素
for (int i = ; i < ; ++i)
{
myList1.push_back(i + );
}
cout << "打印链表1的数据:" << endl;
print(myList1); myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
cout << "打印链表2的数据:" << endl; print(myList2); myList1.merge(myList2);
cout << "合并后,打印链表1的数据:" << endl;
print(myList1);
cout << "合并后,打印链表2的数据:" << endl;
print(myList2); system("pause");
}
运行结果如下图:
代码3:链表1升序,链表2降序。
#include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1, myList2;
// 赋值
myList1.assign(, );
// 插入元素
int nArrayA[] = {, , , , };
myList1.insert(myList1.end(), nArrayA, nArrayA + );
// 追加元素
for (int i = ; i < ; ++i)
{
myList1.push_back(i + );
}
cout << "打印链表1的数据:" << endl;
print(myList1); myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
cout << "打印链表2的数据:" << endl; print(myList2); myList1.merge(myList2);
cout << "合并后,打印链表1的数据:" << endl;
print(myList1);
cout << "合并后,打印链表2的数据:" << endl;
print(myList2); system("pause");
}
运行结果如下图:
代码4:链表1降序,链表2降序。
#include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1, myList2;
// 追加元素
for (int i = ; i > ; --i)
{
myList1.push_back(i + );
}
cout << "打印链表1的数据:" << endl;
print(myList1); myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
cout << "打印链表2的数据:" << endl; print(myList2); myList1.merge(myList2);
cout << "合并后,打印链表1的数据:" << endl;
print(myList1);
cout << "合并后,打印链表2的数据:" << endl;
print(myList2); system("pause");
}
运行结果如下图:
代码5:链表1升序,链表2升序。
#include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1, myList2;
// 赋值
myList1.assign(, );
// 插入元素
int nArrayA[] = {, , , , };
myList1.insert(myList1.end(), nArrayA, nArrayA + );
// 追加元素
for (int i = ; i < ; ++i)
{
myList1.push_back(i + );
}
cout << "打印链表1的数据:" << endl;
print(myList1); myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back(3);
myList2.push_back();
cout << "打印链表2的数据:" << endl; print(myList2); myList1.merge(myList2);
cout << "合并后,打印链表1的数据:" << endl;
print(myList1);
cout << "合并后,打印链表2的数据:" << endl;
print(myList2); system("pause");
}
运行结果如下图:
经过查资料及源码,发现问题是:
list链表合并merge方法注意事项:
1、合并的两个链表必须均默认升序的。即合并之前,两个链表就应该是由小到大顺序排列的。
2、合并完成后,被合并链表(myList2)数据元素被清空。
3、默认是按升序合并。比如上例4,若想按降序进行合并,需要指定降序。
修改后,如下代码:
#include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1, myList2;
// 追加元素
for (int i = ; i > ; --i)
{
myList1.push_back(i + );
}
cout << "打印链表1的数据:" << endl;
print(myList1); myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
myList2.push_back();
cout << "打印链表2的数据:" << endl; print(myList2); myList1.merge(myList2, greater<int>());
cout << "合并后,打印链表1的数据:" << endl;
print(myList1);
cout << "合并后,打印链表2的数据:" << endl;
print(myList2); system("pause");
}
按降序进行合并。前提必须两个链表均为降序有序排列。
(3)remove方法。删除链表中所有值为val的元素。
#include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
// cbegin 返回指向第一个元素的迭代器
// cend 返回指向最后一个元素之后位置的迭代器
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
// 构造函数(默认构造函数)
list<int> myList1;
myList1.assign(, );
myList1.insert(myList1.end(), , );
for (int i = ; i > ; --i)
{
myList1.push_back();
}
for (int i = ; i < ; ++i)
{
myList1.push_front(i + );
}
cout << "打印链表的数据:" << endl;
print(myList1); cout << "删除12后,打印链表数据:";
myList1.remove();
print(myList1); cout << "删除34后,打印链表数据:";
myList1.remove();
print(myList1); system("pause");
} // run out:
/*
打印链表的数据:
19 18 17 16 15 12 12 12 34 34 34 12 12 12 12 12
删除12后,打印链表数据:19 18 17 16 15 34 34 34
删除34后,打印链表数据:19 18 17 16 15
请按任意键继续. . .
*/
(4)remove_if方法。用一元函数判断是否删除元素,若函数返回true,则删除该元素。
应用示例代码如下:
#include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} bool IsDel (int i)
{
return ((i % ) == );
} void main ()
{
int myInts[] = {, , , , , , , , , };
list<int> myList(myInts, myInts + ); cout << "打印链表数据元素:" << endl;
print(myList);
myList.remove_if(IsDel);
cout << "删除(val % 2 == 1)后打印链表数据元素:" << endl;
print(myList); system("pause");
} // run out:
/*
打印链表数据元素:
1 2 3 4 5 6 7 8 9 10
删除(val % 2 == 1)后打印链表数据元素:
2 4 6 8 10
请按任意键继续. . .
*/
(5)unique方法。移除重复元素。
#include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
list<int> myList;
myList.assign(, );
for (int i = ; i < ; ++i)
{
myList.push_front(i + );
}
for (int i = ; i < ; ++i)
{
myList.push_back( + i);
}
myList.insert(myList.end(), , ); print(myList);
myList.unique(); // 移除重复元素
print(myList); system("pause");
} // run out:
/*
6 5 4 3 2 100 100 100 100 100 10 11 12 13 14 45 45 45 45 45
6 5 4 3 2 100 10 11 12 13 14 45
请按任意键继续. . .
*/
(6)splice 粘接方法的三种方式
应用示例代码如下:
#include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
list<int> myList1, myList2, myList3, myList4;
myList1.assign(, );
myList2.push_front();
cout << "打印myList2的数据:" << endl;
print(myList2);
cout << "打印myList1的数据:" << endl;
print(myList1);
// 粘接方法1:splice(iterator pos, list& lst)
// 将myList1链表元素粘接到myList2链表的第一个位置(pos及其后元素均后移)
myList2.splice(myList2.begin(), myList1);
cout << "粘接后,打印myList2的数据:" << endl;
print(myList2);
cout << "粘接后,打印myList1的数据:" << endl;
print(myList1); // 粘接方法2:splice(iterator pos, list& lst, iterator del)
// 将myList1链表元素从第二个开始粘接到myList3链表的第一个位置
myList1.assign(, );
myList3.assign(, );
cout << endl << "打印myList3的数据:" << endl;
print(myList3);
cout << "打印myList1的数据:" << endl;
print(myList1);
myList3.splice(myList3.begin(), myList1, ++myList1.begin());
cout << "粘接后,打印myList3的数据:" << endl;
print(myList3);
cout << "粘接后,打印myList1的数据:" << endl;
print(myList1); // 粘接方法3:splice(iterator pos, list& lst, iterator start, iterator end)
// 将myList1链表元素从第二个开始粘接到myList4链表的第二个位置
myList1.push_back();
myList1.push_back();
myList1.push_back();
myList1.push_back();
myList4.assign(, );
cout << endl << "打印myList4的数据:" << endl;
print(myList4);
cout << "打印myList1的数据:" << endl;
print(myList1);
myList4.splice(++myList4.begin(), myList1, ++myList1.begin(), myList1.end());
cout << "粘接后,打印myList4的数据:" << endl;
print(myList4);
cout << "粘接后,打印myList1的数据:" << endl;
print(myList1); system("pause");
} // run out:
/*
打印myList2的数据:
22
打印myList1的数据:
10 10 10 10 10
粘接后,打印myList2的数据:
10 10 10 10 10 22
粘接后,打印myList1的数据: 打印myList3的数据:
22 22
打印myList1的数据:
11 11
粘接后,打印myList3的数据:
11 22 22
粘接后,打印myList1的数据:
11 打印myList4的数据:
44 44 44 44
打印myList1的数据:
11 12 13 14 15
粘接后,打印myList4的数据:
44 12 13 14 15 44 44 44
粘接后,打印myList1的数据:
11
请按任意键继续. . .
*/
(7)swap方法。交换两个链表中的元素。
应用示例代码如下:
#include <list>
#include <iostream>
using namespace std; // 打印链表数据信息
void print (const list<int> & tempList)
{
list<int>::const_iterator cIter = tempList.cbegin();
for (; cIter != tempList.cend(); ++cIter)
{
cout << (*cIter) << " ";
}
cout << endl;
} void main()
{
list<int> myList1, myList2;
for (int i = ; i < ; ++i)
{
myList1.push_back(rand() % );
}
for (int j = ; j < ; ++j)
{
myList2.push_back(rand() % );
}
cout << "打印myList1的数据:" << endl;
print(myList1);
cout << "打印myList2的数据:" << endl;
print(myList2);
myList1.swap(myList2);
cout << "交换后,打印myList1的数据:" << endl;
print(myList1);
cout << "交换后,打印myList2的数据:" << endl;
print(myList2); system("pause");
}
// run out:
/*
打印myList1的数据:
41 67 34 0 69 24 78 58 62 64
打印myList2的数据:
105 145 81 27 161 91 195 142 27 36
交换后,打印myList1的数据:
105 145 81 27 161 91 195 142 27 36
交换后,打印myList2的数据:
41 67 34 0 69 24 78 58 62 64
请按任意键继续. . .
*/
(8)待续。。。。
【3】list与vector区别总结
数组与链表的优缺点;
数组:
优点:访问效率高,内存为连续的区域。
缺点:添加、删除操作效率低。大小固定,不适合动态存储(不方便动态添加)。
链表:
优点:一般内存不连续。添加、删除效率高。大小可变。
缺点:只能通过指针顺序访问,查询效率低。
Good Good Study, Day Day Up.
顺序 选择 循环 总结
STL容器之list的更多相关文章
- [知识点]C++中STL容器之map
UPDATE(20190416):写完vector和set之后,发现不少内容全部引导到map上了……于是进行了一定的描述补充与更正. 零.STL目录 1.容器之map 2.容器之vector 3.容器 ...
- [知识点]C++中STL容器之set
零.STL目录 1.容器之map 2.容器之vector 3.容器之set 一.前言 继上期的vector之后,我们又迎来了另一个类数组的STL容器——set. 二.用途与特性 set,顾名思义,集合 ...
- [知识点]C++中STL容器之vector
零.STL目录 1.容器之map 2.容器之vector 3.容器之set 一.前言 关于STL和STL容器的概念参见STL系列第一篇——map(见上).今天介绍第二个成员——vector. 二.用途 ...
- STL容器之map
[1]map容器 map 是关联容器.容器中的每一个元素都是由一个键值和一个数据值组成的. set 是一个集合它以其元素作为键值(同一个键值只能出现一次),且默认以升序排列. list 是一个顺序容器 ...
- STL容器之vector
[1]模板类vector 模板类vector可理解为广义数组.广义数组,即与类型无关的数组,具有与数组相同的所有操作. 那么,你或许要问:既然C++语言本身已提供了一个序列式容器array,为什么还要 ...
- C++ STL容器之 stack
STL 中的 stack 是一种容器适配器,而不是一种容器. 它是容器适配器是指,只要支持一系列方法的容器(empty, size, back, push_back, pop_back),都能作为st ...
- STL容器之set
[1]set容器 一个集合(set)是一个容器,它其中所包含的元素的值是唯一的. [2]set容器方法 (1)set构造函数.插入函数.遍历过程 应用示例代码如下: #include <set& ...
- STL容器之deque
[1]deque容器 deque 是对 vector 和 list 优缺点的结合,它是处于两者之间的一种容器. [2]deque方法集 应用示例代码: #include <deque> # ...
- STL容器之Array[转]
转自https://blog.csdn.net/sin_geek/article/details/51067874 作者 Sin_Geek 简介 array在头文件<array> 中定义 ...
随机推荐
- javascript语法(一) 极客时间
脚本和模块 javascript有两种源文件,一种叫脚本,一种叫模块.这个区分主要是在ES6引入的,ES5及之前版本只有一种源文件类型(只有脚本). 脚本是可以有浏览器或者node环境引入执行的,而模 ...
- nginx 负载均衡5种配置方式
nginx 负载均衡5种配置方式 1.轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除. 2.weight 指定轮询几率,weight和访问比率成正比, ...
- es6 学习四 数组的学习
1. Array.from() 语法: Array.from(arrayLike[, mapFn[, thisArg]]) arrayLike 类数组对象 mapFn 如果指定了该参数,新数组中的每个 ...
- CUDNN安装
在英伟达官网下载后解压,然后: cd cuda sudo cp lib64/* /usr/local/cuda/lib64/ sudo cp include/* /usr/local/cuda/inc ...
- Machine Learning in action --LogisticRegession 逻辑回归
本系列主要参考<机器学习实战>,使用python3编译环境,实现书中的相关代码. 1.基本算法 关于梯度上升算法和随机梯度上升算法的选择: 当数据集较小时,使用梯度上升算法: 当数据集较大 ...
- python json 模块
什么是json? json是返回的是字符串格式,把python数据类型列表.字典转换成json字符串格式, 这种格式java php 其他语言都可以认识的字符串,可以跨语言交流. json,用于字符串 ...
- react-native-image-picker iOS设置
效果图,因为我用的是模拟器,所以拍照功能没有效果,不过可从相册选择,下面是具体的效果图 把react-native-image-picker添加到项目 yarn add react-native-im ...
- pycharm如何设置注释的字体颜色
一.pycharm如何设置注释的字体颜色 1.打开pycharm编辑器,file > settings > Editor > Color Scheme > python > ...
- H3C 网管交换机快速配置指南(转)
H3C交换机,5XXX,3XXX,还有部分2XXX系列都带有网管功能,可以帮助网络维护非常好的控制网络.基本的配置顺序: Console接口连接,开启Telnet登陆功能,Telnet后进行具体设置. ...
- [LeetCode] 374. Guess Number Higher or Lower_Easy tag: Binary Search
We are playing the Guess Game. The game is as follows: I pick a number from 1 to n. You have to gues ...