链表(双向) 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.