C++学习笔记_16 线性容器-List容器 2021-05-13

简介: C++学习笔记_16 线性容器-List容器 2021-05-13

链表(双向)  list

不支持对元素的下标访问,在任何位置添加和删除元素,都非常方便。

1. // C++学习笔记_16 线性容器-List容器
2. 
3. #include<iostream>
4. #include<string>
5. #include<list>
6. #include<vector>
7. using namespace std;
8. 
9. template <typename T>
10. void PrintList(const list<T>  &tList)
11. {
12. typename list<T>::const_iterator it;//const_iterator 表示迭代器指向的值不能被修改
13. for (it = tList.begin(); it != tList.end(); it++)  cout << *it << " ";
14.     cout << endl;
15. }
16. 
17. //判断函数是否为偶数
18. bool IsEven(int x){ return !(x & 1);}
19. 
20. bool MyComp(int x, int y){ return  x > y; }
21. 
22. void TestList()
23. {
24.     list<int>  iList1;
25. list<int>  iList2(5);  
26. list<int>  iList3(5, 6); //第二个入参表示默认值
27. list<int>  iList4(iList3);
28. list<int>  iList5(iList4.begin(), iList4.end());
29. 
30. vector<int> iVec({ 1, 4, 7, 2, 5, 8, 3, 6, 9 });
31. list<int> iList6(iVec.begin(), iVec.end());
32. 
33. list<int>  iList7({ 1, 2, 3, 4, 5, 6, 7, 8, 9 });
34. 
35. //iList1.empty(): 判断容器是否为空
36. //iList1.size() : 获取容器中元素个数
37. //iList1.max_size()
38. 
39.     cout << "iList2:";
40. PrintList(iList2);
41. //插入元素
42. //后端插入: push_back(xxx)
43. //前端插入: push_front(xxx)
44. //指定位置插入: insert(it, xxx)
45. //指定位置插入 N 个 xxx :  insert(it, N, xxx)
46. //指定位置插入 一段区间的元素: insert(it, itBegin,itEnd)
47.     iList2.push_back(11);
48.     iList2.push_front(22);  //比 vector 新增的插入方式
49.     iList2.insert(++iList2.begin(), 33);//iList2.begin() + 1 迭代器不支持加法
50.     iList2.insert(--iList2.end(), 2, 44);
51.     iList2.insert(iList2.begin(), iVec.begin(), iVec.begin() + 2);
52.     cout << "iList2:";
53. PrintList(iList2);
54.     cout << endl;
55. 
56. //删除元素
57. //后端删除:          pop_back()
58. //前端删除:          pop_front()
59. //删除某个位置的元素:erase(it)
60. //删除一段区间的元素: erase(itBegin, itEnd)
61. //清空链表            clear()
62.     iList2.pop_back();
63.     iList2.pop_front();
64.     cout << "iList2:";
65. PrintList(iList2);
66. 
67.     iList2.erase(++iList2.begin());
68.     cout << "iList2:";
69. PrintList(iList2);
70. 
71.     iList2.erase(++iList2.begin(), --iList2.end());//删除中间元素,保留首尾
72.     cout << "iList2:";
73. PrintList(iList2);
74. 
75.     iList2.clear(); //清空
76. 
77.     cout << endl << "iList7:";
78. PrintList(iList7);
79. //输出 iList7 的第一个元素
80.     cout << "iList7第一个元素:" << iList7.front() << endl;
81.     cout << "iList7第一个元素:" << *(iList7.begin()) << endl;
82.     cout << "iList7第一个元素:" << *(--iList7.rend()) << endl;
83.     cout << endl;
84. 
85.     cout << "iList7第末个元素:" << iList7.back() << endl;
86.     cout << "iList7第末个元素:" << *(--iList7.end()) << endl;
87.     cout << "iList7第末个元素:" << *(iList7.rbegin()) << endl;
88. 
89. /*
90.     list<int>::iterator it = iList7.begin();
91.     int i = 0;
92.     while (i++ < 7) it++;
93.     */
94. 
95. //swap 交换两个list
96. //assign 重置 list 中的元素
97. //resize(n), resize(n, xxx)  扩充(减少)元素个数到 n 个
98.     iList1.swap(iList2);
99. 
100.     iList2.assign(4, 8);
101.     iList2.assign(iVec.begin(), iVec.end());
102.     iList2.assign({ 1, 3, 5, 7, 2, 4, 6, 8 });
103. 
104.     iList2.resize(10, 3);
105. 
106. //list 中的一些专用函数
107. //remove(xxx)     删除所有等于某个值的元素
108. //remove_if(COND) 删除满足某个条件的元素
109. //reverse         链表逆序
110. //unique          去掉相邻重复的元素,仅保留一个(不相邻的可以重复)
111. //sort            对list中的元素进行排序 (默认升序排列)
112. //merge           对 list 进行归并排序 (把一个list归并到另一个中)
113. //                要求归并前,两个list都是有序的 (默认升序)
114. //splice          切片:把一个链表的若干个元素,剪切到另一个链表的某个位置
115.     iList2.assign({ 1, 2, 5, 3, 4, 9, 8, 7, 5 });
116.     cout << endl << "iList2:";
117. PrintList(iList2);
118. 
119.     iList2.remove(5); //按照值进行删除
120.     cout << "iList2:";
121. PrintList(iList2);
122. 
123.     iList2.remove_if(IsEven);
124.     cout << "iList2:";
125. PrintList(iList2);
126. 
127.     iList2.reverse(); //逆序
128.     cout << "iList2:";
129. PrintList(iList2);
130. 
131.     cout << endl;
132.     iList1.assign({ 1, 2, 2, 3, 3, 3, 5, 6, 5, 7, 2, 1 });
133.     iList1.unique();
134.     cout << "iList1:";
135. PrintList(iList1);
136. 
137.     iList1.sort();
138.     cout << "iList1:";
139. PrintList(iList1); 
140. 
141.     cout << endl;
142. //这里默认升序, 如果我们想降序?  --》 传入一个 排序规则
143.     iList1.assign({ 1, 3, 5, 7, 2, 4, 6, 8 });
144.     iList1.sort(MyComp); //在排序的时候,比较两个值,使用 MyComp(*it1,*it2) 来比较
145. //通过这个函数的返回值,来决定两个值的顺序
146.     cout << "iList1:";
147. PrintList(iList1);
148.     cout << endl;
149. 
150.     iList1.assign({ 1, 3, 5, 7 });
151.     iList2.assign({ 2, 4, 6, 8 });
152. 
153.     iList1.merge(iList2);//1:要求 iList1和iList2都是升序
154. //2:归并完成后,iList2 变成空的了 (节点移到了 iList1中)
155.     cout << "iList1:";
156. PrintList(iList1);
157.     cout << "iList2:";
158. PrintList(iList2);
159. 
160. //如果 iList1 和 iList2 降序归并?
161.     iList1.assign({ 7, 5, 3, 1 });
162.     iList2.assign({ 8, 6, 4, 2 });
163.     iList1.merge(iList2, MyComp); //自定义排序规则
164.     cout << "iList1:";
165. PrintList(iList1);
166.     cout << "iList2:";
167. PrintList(iList2);
168.     cout << endl;
169. 
170.     iList1.assign({ 1, 3, 5, 7, 9 });
171.     iList2.assign({ 2, 4, 6, 8, 10 });
172. 
173. //1: 剪切一个元素  splice(it, srcList, srcIt)
174. //   把 iList2 的 第二个元素[++iList2.begin()]   
175. //                剪切到   iList1.begin() 位置
176.     iList1.splice(iList1.begin(), iList2, ++iList2.begin());
177.     cout << "iList1:";
178. PrintList(iList1);
179. 
180.     cout << "iList2:";
181. PrintList(iList2);
182. 
183. //2: 剪切一段元素  splice(it, srcList, itBegin, itEnd)
184. //   把 iList2 中 一段区间的元素 [++iList2.begin(), --iList2.end())
185. //                剪切到 iList1.end()
186.     iList1.splice(iList1.end(), iList2, ++iList2.begin(), --iList2.end());
187.     cout << "iList1:";
188. PrintList(iList1);
189. 
190.     cout << "iList2:";
191. PrintList(iList2);
192. 
193. //3: 整个链表剪切  splice(it, srcList)
194. //   把 iList2 所有元素,剪切到 iList1 的 ++iList1.begin() 位置
195.     iList1.splice(++iList1.begin(), iList2);
196.     cout << "iList1:";
197. PrintList(iList1);
198. 
199.     cout << "iList2:";
200. PrintList(iList2);
201. 
202. }
203. 
204. //作业 1:
205. // list<int> iList({1,2,3,4,5,6,7,8,9,3,4,5,6,7});
206. // 写一个仿函数类 IsMore 支持删除 > N 的元素
207. // iList.remove_if(IsMore(3))
208. // iList.remove_if(IsMore(4))
209. // ......
210. 
211. //作业2:
212. // list<string> sList({"aaa", "BB", "CCCC", "AA", "bbbb", "ccc"})
213. // 我们写几个排序规则 MyCompS1(string &s1, string &s2), MyCompS2, ...
214. // 分别实现:调用 sList.sort(MyCompS1), sList.sort(MyCompS2), ...
215. //1: 按照 ASCII 降序排列
216. //2:  按照长度升序排列 (长度相等,则比较 ASCII 升序)
217. //3: 按照长度降序排列 (长度相等,则比较 ASCII 降序)
218. class IsMore
219. {
220. private:
221. int x;
222. public:
223. IsMore(int N) :x(N){}
224. bool operator ()(int a)
225.     {
226. return a > x;
227.     }
228. };
229. 
230. 
231. bool MyCompS1(const string &s1, const string &s2){return s1 > s2;}
232. 
233. bool MyCompS2(const string &s1, const string &s2)
234. {
235. if (s1.length() == s2.length())
236. return s1 < s2; //就是逐个字符比较 ASCII
237. else
238. return s1.length() < s2.length();
239. }
240. 
241. bool MyCompS3(const string &s1, const string &s2)
242. {
243. if (s1.length() == s2.length())
244. return s1 > s2;
245. else
246. return s1.length() > s2.length();
247. }
248. 
249. void TestWork()
250. {
251. list<int> iList({ 1, 2, 3, 4, 5, 6, 7, 8, 9, 3, 4, 5, 6, 7 });
252. 
253.     iList.remove_if(IsMore(5));
254. 
255.     cout << "iList: ";
256. PrintList(iList);
257. 
258. list<string> sList({ "aaa", "BB", "CCCC", "AA", "bbbb", "ccc" });
259. 
260.     sList.sort();//默认排序:按照 ASCII 升序排列
261.     cout << "sList: ";
262. PrintList(sList);
263. 
264. //1:按照 ASCII 降序排列
265.     sList.sort(MyCompS1);
266.     cout << "sList: ";
267. PrintList(sList);
268. 
269. //2: 按照 先长度,后 ASCII 升序排列
270.     sList.sort(MyCompS2);
271.     cout << "sList: ";
272. PrintList(sList);
273. 
274. //3: 按照 先长度,后 ASCII 降序排列
275.     sList.sort(MyCompS3);
276.     cout << "sList: ";
277. PrintList(sList);
278. }
279. 
280. int main()
281. {
282. //TestList();
283. TestWork();
284. system("pause");
285.  return 0;
286. }
287.

 

相关文章
|
23小时前
|
存储 C++ 容器
【C++】哈希(模拟实现unordered系列容器)
【C++】哈希(模拟实现unordered系列容器)
|
1天前
|
设计模式 存储 编译器
【C++ STL】容器适配器(Stack & Queue & Priotity_Queue)-- 详解(下)
【C++ STL】容器适配器(Stack & Queue & Priotity_Queue)-- 详解(下)
|
1天前
|
存储 算法 C语言
【C++ STL】容器适配器(Stack & Queue & Priotity_Queue)-- 详解(上)
【C++ STL】容器适配器(Stack & Queue & Priotity_Queue)-- 详解(上)
|
1天前
|
存储 编译器 C++
【C++】List -- 详解(下)
【C++】List -- 详解(下)
|
1天前
|
存储 算法 C++
【C++】List -- 详解(上)
【C++】List -- 详解(上)
|
6天前
|
C++ 容器
|
8天前
|
调度 C++ 容器
【C++】手搓 list 容器
本文我们实现了STL库中重要的list 的模拟实现,其中最重要莫过于迭代器的封装类的书写,这是前所未有的操作(对于我来说,我是第一次使用这种结构)。通过list 的模拟实现也帮我们巩固了类与对象的知识,也强化了指针操作的思路。欢迎大家讨论分析。
14 1
|
8天前
|
存储 C++ 容器
【C++】vector容器初步模拟
我们初步完成了对vector 的模拟实现,但是依然有问题,比如不支持string等特殊类型。所以下一篇文章我们来一起完善一下。
16 0
【C++】vector容器初步模拟
|
8天前
|
存储 安全 算法
Java一分钟之-Java集合框架入门:List接口与ArrayList
【5月更文挑战第10天】本文介绍了Java集合框架中的`List`接口和`ArrayList`实现类。`List`是有序集合,支持元素重复并能按索引访问。核心方法包括添加、删除、获取和设置元素。`ArrayList`基于动态数组,提供高效随机访问和自动扩容,但非线程安全。文章讨论了三个常见问题:索引越界、遍历时修改集合和并发修改,并给出避免策略。通过示例代码展示了基本操作和安全遍历删除。理解并正确使用`List`和`ArrayList`能提升程序效率和稳定性。
12 0
|
8天前
|
存储 安全 Java
【JAVA基础篇教学】第八篇:Java中List详解说明
【JAVA基础篇教学】第八篇:Java中List详解说明