C++进阶-3-5-list容器
1 #include<iostream> 2 #include<list> 3 #include<algorithm> 4 using namespace std; 5 6 // list容器 7 8 void printList(const list<int>& L) { 9 10 for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) { 11 cout << *it << " "; 12 } 13 cout << endl; 14 } 15 16 // 1.构造函数 17 void test01() { 18 19 // 创建list容器 20 list<int> L1; // 默认构造 21 22 // 添加数据 23 L1.push_back(10); 24 L1.push_back(20); 25 L1.push_back(30); 26 L1.push_back(40); 27 28 // 遍历容器 29 printList(L1); 30 31 32 // 区间构造 33 list<int>L2(L1.begin(), L1.end()); 34 printList(L2); 35 36 // 拷贝构造 37 list<int>L3(L2); 38 printList(L3); 39 40 //n个elem 41 list<int>L4(10, 200); 42 printList(L4); 43 44 } 45 46 // 2.赋值和交换 47 void test02() { 48 49 list<int> L1; 50 51 L1.push_back(10); 52 L1.push_back(20); 53 L1.push_back(30); 54 L1.push_back(40); 55 56 printList(L1); 57 58 // 赋值操作 59 list<int>L2; 60 L2 = L1; 61 printList(L2); 62 63 list<int>L3; 64 L3.assign(L2.begin(), L2.end()); 65 printList(L3); 66 67 list<int>L4; 68 L4.assign(10, 100); 69 printList(L4); 70 71 // 交换操作 72 list<int>L5; 73 L5.assign(5, 22); 74 75 cout << "交换前:" << endl; 76 printList(L1); 77 printList(L5); 78 79 L1.swap(L5); 80 cout << "交换后:" << endl; 81 printList(L1); 82 printList(L5); 83 84 } 85 86 // 3.大小操作 87 void test03() { 88 89 list<int> L1; 90 91 L1.push_back(10); 92 L1.push_back(20); 93 L1.push_back(30); 94 L1.push_back(40); 95 96 printList(L1); 97 98 // 判断list容器是否为空 99 if (L1.empty()) { 100 cout << "L1为空" << endl; 101 } 102 else 103 { 104 cout << "L1不为空" << endl; 105 cout << "L1的元素个数为:" << L1.size() << endl; 106 } 107 108 // 重新指定大小 109 L1.resize(20); 110 printList(L1); 111 112 L1.resize(30, 22); 113 printList(L1); 114 115 L1.resize(4); 116 printList(L1); 117 } 118 119 // 4.插入和删除 120 void test04() { 121 122 list<int>L; 123 124 // 头插 125 L.push_front(10); 126 L.push_front(20); 127 L.push_front(30); 128 129 // 尾插 130 L.push_back(100); 131 L.push_back(200); 132 L.push_back(300); 133 134 printList(L); 135 136 // 头删 137 L.pop_front(); 138 139 // 尾删 140 L.pop_back(); 141 142 printList(L); 143 144 //insert插入 145 L.insert(L.begin(), 1000); 146 printList(L); 147 148 list<int>::iterator it = L.begin(); 149 L.insert(++it, 345); 150 printList(L); 151 152 // 删除 153 it = L.begin(); 154 L.erase(it); 155 printList(L); 156 157 // 移除 158 L.push_back(100000); 159 printList(L); 160 L.remove(100000); // 删除容器中所有与elem值匹配的元素 161 printList(L); 162 163 // 清空 164 L.clear(); 165 printList(L); 166 167 } 168 169 // 5.数据存取 170 void test05() { 171 172 list<int> L1; 173 174 L1.push_back(10); 175 L1.push_back(20); 176 L1.push_back(30); 177 L1.push_back(40); 178 179 printList(L1); 180 181 // L[0]; // 不能用 [] 访问list容器中的元素 182 // L.at(0); // 不可以用 at 方式访问list容器中的元素 183 // 原因:list本质链表,不是用连续线性空间存储数据,迭代器也是不支持随机访问的 184 185 cout << "第一个元素是:" << L1.front() << endl; 186 cout << "最后一个元素是:" << L1.back() << endl; 187 188 // 验证迭代器是不支持随机访问的 189 list<int>::iterator it = L1.begin(); 190 it++; // 支持双向 191 it--; 192 //it = it + 1; // 报错,不支持随机访问 193 } 194 195 // 6.反转和排序 196 197 bool myCompare(int v1, int v2) { 198 // 降序 就让第一个数 > 第二个数 199 return v1 > v2; 200 } 201 202 void test06() { 203 204 list<int> L1; 205 206 L1.push_back(30); 207 L1.push_back(20); 208 L1.push_back(60); 209 L1.push_back(40); 210 L1.push_back(10); 211 212 cout << "反转前:" << endl; 213 printList(L1); 214 215 // 反转 216 L1.reverse(); 217 cout << "反转后:" << endl; 218 printList(L1); 219 220 221 // 排序,sort成员函数 222 cout << "排序前:" << endl; 223 printList(L1); 224 225 // 所有不支持随机访问迭代器的容器,不可以用标准的sort算法 226 //sort(L1.begin(), L1.end()); // 报错 227 // 不支持随机访问迭代器的容器,内部会提供对应的一些算法 228 229 L1.sort(); // 默认,升序 230 231 cout << "升序,排序后:" << endl; 232 printList(L1); 233 234 // 降序 235 236 L1.sort(myCompare); 237 238 cout << "降序,排序后:" << endl; 239 printList(L1); 240 } 241 242 // 7.排序案例,自定义数据类型 243 // 案例描述: 244 // 将Person自定义数据类型进行排序,Person中有属性:姓名,年龄,身高 245 // 排序规则: 246 // 按照年龄进行升序,如果年龄相同,按照身高进行降序 247 248 class Person { 249 public: 250 Person(string name, int age, int height) { 251 this->m_Name = name; 252 this->m_Age = age; 253 this->m_Height = height; 254 } 255 256 string m_Name; 257 int m_Age; 258 int m_Height; 259 }; 260 261 // 比较自定义数据类型 262 bool comparePerson(Person& p1, Person& p2) { 263 if (p1.m_Age == p2.m_Age) { 264 return p1.m_Height > p2.m_Height; 265 } 266 else 267 { 268 return p1.m_Age < p2.m_Age; 269 } 270 } 271 272 void test07() { 273 274 // 创建容器 275 list<Person> L; 276 277 // 准备数据 278 Person p1("刘备", 35, 175); 279 Person p2("曹操", 45, 180); 280 Person p3("孙权", 40, 170); 281 Person p4("赵云", 25, 190); 282 Person p5("张飞", 35, 160); 283 Person p6("关羽", 35, 200); 284 285 // 插入数据 286 L.push_back(p1); 287 L.push_back(p2); 288 L.push_back(p3); 289 L.push_back(p4); 290 L.push_back(p5); 291 L.push_back(p6); 292 293 // 打印数据 294 for (list<Person>::iterator it = L.begin(); it != L.end(); it++) { 295 cout << "姓名:" << (*it).m_Name << " 年龄:" << it->m_Age << " 身高:" << it->m_Height << endl; 296 } 297 298 // 排序 299 cout << "-----------------------------" << endl; 300 cout << "排序后:" << endl; 301 L.sort(comparePerson); 302 for (list<Person>::iterator it = L.begin(); it != L.end(); it++) { 303 cout << "姓名:" << (*it).m_Name << " 年龄:" << it->m_Age << " 身高:" << it->m_Height << endl; 304 } 305 306 } 307 308 309 int main() { 310 311 // 1.构造函数 312 //test01(); 313 314 // 2.赋值和交换 315 //test02(); 316 317 // 3.大小操作 318 //test03(); 319 320 // 4.插入和删除 321 //test04(); 322 323 // 5.数据存取 324 //test05(); 325 326 // 6.反转和排序,sort成员函数 327 //test06(); 328 329 // 7.排序案例 330 test07(); 331 332 system("pause"); 333 334 return 0; 335 } 336 337 // 总结 338 // 339 // list 容器 340 // 341 // 功能:将数据进行链式存储 342 // 343 // 链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的 344 // 345 // list组成:链表由一系列节点组成 346 // 节点组成:一个存储数据元素的数据域,另一个是存储下一个节点地址的指针域 347 // 348 // STL中的链表是一个双向循环列表 349 // 350 // 优点: 351 // 1.可以对任意位置进行快速插入和删除元素 352 // 2.采用动态存储分配,不会造成内存浪费和已出 353 // 缺点: 354 // 1.空间(指针域)和时间(遍历)额外耗费较大 355 // 2.容器遍历速度,没有数组块 356 // 357 // 链表的存储空间并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器 358 // 359 // List重要性质:插入、删除操作不会造成原有list迭代器的失效,这在vector是不成立的 360 //