目錄
- 1.list容器基本概念
- (1)list的優缺點
- 2.創建list容器
- 3.list容器賦值和交換
- 4.list大小操作
- 5.list插入和洗掉
- 6.list資料存取
- 7.list反轉和排序
- list實戰(學生成績管理系統)
1.list容器基本概念
(1)list容器實際上就是一個鏈表,不同于vector容器,list容器是通過指標將資料鏈式儲存起來;

(2)鏈表是由一系列結點組成的,每一個結點由儲存資料的資料域和儲存下一個資料的地址的指標域組成;
鏈表的知識在之前的文章中**線性表的鏈式存盤結構 ( 鏈表 ).**
list容器中的鏈表是一個雙向回圈鏈表,如下圖所示;

(1)list的優缺點
優
1 . 采用動態存盤分配,不會造成記憶體浪費和溢位;
2 . 鏈表執行插入和洗掉操作十分方便,修改指標即可,不需要移動大量元素,
缺
1 .list鏈表的訪問不支持隨機訪問,只能使用迭代器訪問,操作較復雜
2 . 鏈表靈活,但是空間(指標域)和時間(遍歷)額外耗費較大,遍歷速度沒有陣列快,且占用空間比陣列大,
3 . list有一個重要的性質,插入操作和洗掉操作都不會造成原有list迭代器的失效,這在vector是不成立的,
好了,理論知識就到這里,我們主要靠實戰舉例理解
2.創建list容器
建構式原型:(和vector基本相同)
list<T> lst; //list默認構造形式:
list(begin,end); //建構式將[begin, end)區間中的元素拷貝給本身,
list(n,e); //建構式將n個e賦給給本身,
list(const list &lst); //拷貝建構式
示例
#include<iostream>
using namespace std;
#include <list>//C++ 中的容器使用之前都得包含相應頭檔案
void showList01(const list<int>& L) //唯一一種方式列印list容器中的資料,因為list容器只能通過迭代器訪問
{
for (list<int>::const_iterator p = L.begin(); p != L.end(); p++) {
cout << *p << " ";
}
cout << endl;
}
void testit()
{
list<int>L1;
for (int i = 3; i < 50; i += 10)
{
L1.push_back(i);
}
showList01(L1);
list<int>L2(L1.begin(), L1.end());
showList01(L2);
list<int>L3(L2);
showList01(L3);
list<int>L4(10, 666);
showList01(L4);
}
int main() {
testit();
system("pause");
return 0;
}
運行結果

3.list容器賦值和交換
介面函式原型(和vector基本相同)
assign(begin, end); //將[begin, end)區間中的資料賦值給容器,
assign(n, t); //將n個t拷貝賦值給本身,
list& operator=(const list &lst); //多載等號運算子
swap(lst); //將lst與本身的元素互換,
示例
#include<iostream>
using namespace std;
#include <list>//C++ 中的容器使用之前都得包含相應頭檔案
void showList01(const list<int>& L) //唯一一種方式列印list容器中的資料,因為list容器只能通過迭代器訪問
{
for (list<int>::const_iterator p = L.begin(); p != L.end(); p++) {
cout << *p << " ";
}
cout << endl;
}
//賦值和交換
void testit01()
{
list<int>L1;
for (int i = 3; i < 50; i += 10)
{
L1.push_back(i);
}
showList01(L1);
//賦值
list<int>L2;
L2 = L1;
showList01(L2);
list<int>L3;
L3.assign(L2.begin(), L2.end());
showList01(L3);
list<int>L4;
L4.assign(10, 33);
showList01(L4);
}
//交換
void testit02()
{
list<int>L1;
for (int i = 3; i < 50; i += 10)
{
L1.push_back(i);
}
list<int>L2;
L2.assign(10, 66);
cout << "交換前: " << endl;
showList01(L1);
showList01(L2);
cout << endl;
L1.swap(L2);
cout << "交換后: " << endl;
showList01(L1);
showList01(L2);
}
int main() {
testit01();
cout << "***********下一個測驗案例**********" << endl;
testit02();
system("pause");
return 0;
}
運行結果

4.list大小操作
介面函式原型(和vector基本相同)
size(); //回傳容器中元素的個數
empty(); //判斷容器是否為空
resize(num); //重新指定容器的長度為num,若容器變長,則以默認值填充新位置,
? //如果容器變短,則末尾超出容器長度的元素被洗掉,
resize(num, elem); //重新指定容器的長度為num,若容器變長,則以elem值填充新位置,若容器變短,則洗掉多余的部分
示例
#include<iostream>
using namespace std;
#include <list>//C++ 中的容器使用之前都得包含相應頭檔案
void showList01(const list<int>& L) //唯一一種方式列印list容器中的資料,因為list容器只能通過迭代器訪問
{
for (list<int>::const_iterator p = L.begin(); p != L.end(); p++) {
cout << *p << " ";
}
cout << endl;
}
//大小操作
void testit01()
{
list<int>L1;
for (int i = 3; i < 50; i += 10)
{
L1.push_back(i);
}
showList01(L1);
if (L1.empty())
{
cout << "L1為空" << endl;
}
else
{
cout << "L1不為空" << endl;
cout << "L1的大小為: " << L1.size() << endl;
}
//重新指定大小
L1.resize(10);
showList01(L1);
L1.resize(2);
showList01(L1);
}
int main() {
testit01();
system("pause");
return 0;
}
運行結果

5.list插入和洗掉
介面函式原型.(和vector有區別點)
push_back(elem);//在容器尾部加入一個元素
pop_back();//洗掉容器中最后一個元素
push_front(elem);//在容器開頭插入一個元素
pop_front();//從容器開頭移除第一個元素
insert(pos,elem);//在pos位置插elem元素的拷貝,回傳新資料的位置,
//pos為迭代器位置
insert(pos,n,elem);//在pos位置插入n個elem資料,無回傳值,
//pos為迭代器位置
insert(pos,beg,end);//在pos位置插入[beg,end)區間的資料,無回傳值,
//pos為迭代器位置
clear();//移除容器的所有資料
erase(beg,end);//洗掉[beg,end)區間的資料,回傳下一個資料的位置,
//beg,end為迭代器,也可通過迭代器++改變區間
erase(pos);//洗掉pos位置的資料,回傳下一個資料的位置,
remove(elem);//洗掉容器中所有與elem值匹配的元素,
示例
#include<iostream>
using namespace std;
#include <list>//C++ 中的容器使用之前都得包含相應頭檔案
void showList01(const list<int>& L) //唯一一種方式列印list容器中的資料,因為list容器只能通過迭代器訪問
{
for (list<int>::const_iterator p = L.begin(); p != L.end(); p++) {
cout << *p << " ";
}
cout << endl;
}
//插入和洗掉
void testit01()
{
list<int> L;
//尾插fa
L.push_back(11);
L.push_back(22);
L.push_back(33);
//頭插af
L.push_front(150);
L.push_front(250);
L.push_front(350);
showList01(L);
//尾刪fa
L.pop_back();
showList01(L);
//頭刪fa
L.pop_front();
showList01(L);
//插入fa
list<int>::iterator p = L.begin();
L.insert(++p, 888);
showList01(L);
//洗掉af
p = L.begin();
L.erase(++p);
showList01(L);
//移除fa
L.push_back(9999);
L.push_back(9999);
L.push_back(999);
showList01(L);
L.remove(9999);
showList01(L);
//清空fa
L.clear();
showList01(L);
}
int main() {
testit01();
system("pause");
return 0;
}
運行結果

6.list資料存取
介面函式原型:
front()//回傳第一個資料
back()//回傳第二個資料
//只能通過迭代器訪問
示例
#include<iostream>
using namespace std;
#include <list>//C++ 中的容器使用之前都得包含相應頭檔案
//資料存取
void testit01()
{
list<int>L1;
for (int i = 3; i < 50; i += 10)
{
L1.push_back(i);
}
//list不支持at訪問資料和[]方式訪問資料
//只能通過迭代器訪問
cout << "第一個元素為: " << L1.front() << endl;
cout << "最后一個元素為: " << L1.back() << endl;
//list容器的迭代器是雙向迭代器,不支持隨機訪問
list<int>::iterator it = L1.begin();
//it = it + 1;//錯誤,不可以跳躍訪問,即使是+1
it++;
cout << "第二個元素為: " << *it << endl;
it++;
cout << "第三個元素為: " << *it << endl;
}
int main() {
testit01();
system("pause");
return 0;
}
7.list反轉和排序
介面函式原型
reverse(); //反轉鏈表
sort(); //鏈表排序
//兩者都不是STL中的演算法函式,而是list容器中自帶的介面函式,用法也并不相同
示例
#include<iostream>
using namespace std;
#include <list>//C++ 中的容器使用之前都得包含相應頭檔案
void showList01(const list<int>& L) //唯一一種方式列印list容器中的資料,因為list容器只能通過迭代器訪問
{
for (list<int>::const_iterator p = L.begin(); p != L.end(); p++) {
cout << *p << " ";
}
cout << endl;
}
bool My_sortway(int a, int b)
{
return a > b;
}
//反轉和排序
void test01()
{
list<int> L;
L.push_back(99);
L.push_back(33);
L.push_back(22);
L.push_back(77);
showList01(L);
//反轉容器的元素
L.reverse();
cout << "反轉后 :";
showList01(L);
//排序
L.sort(); //默認的排序規則 從小到大
cout << "從小到大排序后 :";
showList01(L);
L.sort(My_sortway); //指定規則,從大到小
cout << "從大到小排序后 :";
showList01(L);
}
int main() {
test01();
system("pause");
return 0;
}
運行結果

list實戰(學生成績管理系統)
題目要求:
1 .制作一個學生成績單管理系統
2 .將student自定義資料型別進行排序,student中屬性有姓名、年齡、語文成績,數學成績,英語成績
排序規則:按照總成績sum進行降序,如果總成績sum相同按照語文成績進行降序
源代碼
#include<iostream>
using namespace std;
#include <list>
#include <string>
class Student {
public:
Student(string name, int ch, int ma,int e) {
m_Name = name;
chinese = ch;
math = ma;
English = e;
sum = ch + ma + e;
}
public:
string m_Name; //姓名
int chinese; //語文成績
int math; //數學成績
int English;//英語成績
int sum;//總成績
};
bool ComparePerson(Student& p1, Student& p2)//定義sort排序從大到小
{
if (p1.sum == p2.sum) {
return p1.sum < p2.sum;
}
else
{
return p1.chinese < p2.chinese;
}
}
void test() {
list<Student> k;
Student p1("杜雯菲", 88,77,95);
Student p2("杜蚊分", 67,58,26);
Student p3("李八八", 95,77,88);
Student p4("趙二蛋",86,75,68);
Student p5("王小牛", 86,46,86);
Student p6("張小哈",89,57,68);
k.push_back(p1);
k.push_back(p2);
k.push_back(p3);
k.push_back(p4);
k.push_back(p5);
k.push_back(p6);
for (list<Student>::iterator it = k.begin(); it != k.end(); it++) {
cout << "姓名: " << it->m_Name << " 語文: " << it->chinese
<< " 數學: " << it->math << " 英語: " << it->English<< " 總成績: " << it->sum<< endl;
}
cout << "---------------------------------" << endl;
k.sort(ComparePerson); //排序
cout << "排序后" << endl;
for (list<Student>::iterator it = k.begin(); it != k.end(); it++) {
cout << "姓名: " << it->m_Name << " 語文: " << it->chinese
<< " 數學: " << it->math << " 英語: " << it->English << " 總成績: " << it->sum << endl;
}
}
int main() {
test();
system("pause");
return 0;
}
運行結果

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/397544.html
標籤:其他
下一篇:淺談元宇宙
