1. 程式人生 > 其它 >C++進階-3-5-list容器

C++進階-3-5-list容器

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 //