list容器
list容器基本概念
功能:将数据进行链式存储
链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链实现的
链表的组成:链表由一些列结点组成
结点的组成:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域
STL中的链表是一个双向循环链表
优点:可以对任意位置进行快速插入和删除元素
缺点:容器的遍历速度没有数组快,占用空间比较大(指针占用空间)
由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支撑前移和后移,属于双向迭代器
list的优缺点
list 的优点:
-
采用动态存储分配,不会造成内存浪费和溢出
-
链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
list 的缺点:
-
链表灵活,但是空间(指针域)和时间(遍历)额外耗费较大
-
list有一个重要的性质,插入操作和删除操作都不会造成原有list 迭代器的失效,这在vector是不成立的
总结:
-
STL中list和vector是两个最常被使用的容器,各有优缺点
list容器的操作(表格)
函数 | 意义 | 使用 |
---|---|---|
assign(beg,end) | 将(beg,end)区间中的数据拷贝赋值给本身 | d.assign(a.begin(), a.end()); |
assign(n,elem) | 将n个elem拷贝赋值给本身 | y.assign(q, p); |
list&operator=(const list&lst) | 重载等号运算符 | list<int>v; v = a; |
swap(lst) | 将lst与本身的元素互换 | a.swap(y); |
size() | 返回容器中元素的个数 | cout << "容器大小为" <<a.size()<< endl; |
empty() | 判断容器是否为空 | if (a.empty()) { cout << "这是一个空容器" << endl; } else { cout << "容器不为空" << endl; cout << "容器大小为" <<a.size()<< endl; } |
resize() | 重新指定容器长度为num,若容器变长,则以默认值填充新位置,若容器变短,则末尾超出容器长度的元素被删除 | a.resize(2); |
resize(num,elem) | 重新指定容器的长度为num,若容器变长,则以elem值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除 | a.resize(10, 2); |
push_back(elem) | 在容器尾部加入一个元素 | for (int i = 0; i < b; i++) { int g; cout << "输入要存入的数字" << endl; cin >> g; a.push_back(g); } |
pop_back() | 删除容器中最后一个元素 | for (int i; i < b; i++) { a.pop_back(); } |
push_front(elem) | 在容器开头插入一个元素 | for (int i; i < b; i++) { int y; cout << "输入要存入的数据" << endl; cin >> y; a.push_front(y); } |
pop_front() | 从容器开头移除第一个元素 | for (int i; i < b; i++) { a.pop_front(); } |
insert(pos,elem) | 在pos位置插elem元素的拷贝,返回新数据的位置 | a.insert(a.begin (), d); //可以a.gegin()++ 但是不能c+a.和 a.+c导致无法控制 |
insert(pos,n,elem) | 在pos位置插入n个elem数据,无返回值 | a.insert(a.begin(), b, d); |
insert(pos,beg,end) | 在pos位置插入(beg,end)区间的数据,无返回值 | b.insert(b.begin(), a.begin(), a.end()); |
clear() | 移除容器的所有数据 | b.clear(); |
erase(beg,end) | 删除(beg,end)区间的数据,返回下一个数据的位置 | a.erase(a.begin(), a.end()); |
erase(pos) | 删除pos位置的数据,返回下一个数据的位置 | a.erase(a.begin()); |
remove(elem) | 删除容器中所有与elem值匹配的元素 | c.remove(n); //所有的n都删除 |
front() | 返回第一个元素 | cout << c.front() << endl; |
back() | 返回最后一个元素 | cout << c.back() << endl; |
reverse() | 反转链表 | a.reverse(); reserve预留空间reverse反转 |
sort() | 链表排序 |
list构造函数
功能描述
-
创建list容器
函数原理
#include<iostream>
#include<list>
using namespace std;
void printlist(list<int>a)
{
for (list<int>::iterator it = a.begin(); it != a.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
list<int>a;
int b;
cout << "输入要在链表存入的元素数" << endl;
cin >> b;
for (int i = 0; i < b; i++)
{
int c;
cout << "输入要存入的数字" << endl;
cin >> c;
a.push_back(c);
}
printlist(a);
list<int>d(a);
printlist(d);
int q;
int p;
cout << "输入链表要存入数字" << endl;
cin >> p;
cout << "输入链表要存入数字数量" << endl;
cin >> q;
list<int>e(q, p);
printlist(e);
list<int>x(e.begin(),a.end());
printlist(x);
system("pause");
return 0;
}
list赋值和交换
功能描述:
-
给list容器进行赋值,以及交换list容器
#include<iostream>
#include<list>
using namespace std;
void printlist(list<int>a)
{
for (list<int>::iterator it = a.begin(); it != a.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
list<int>a;
int b;
cout << "输入要存入的数量" << endl;
cin >> b;
for (int i = 0; i < b; i++)
{
int g;
cout << "输入要存入的数字" << endl;
cin >> g;
a.push_back(g);
}
printlist(a);
list<int>d;
d.assign(a.begin(), a.end());
printlist(d);
list<int>y;
int q;
int p;
cout << "输入链表要存入数字" << endl;
cin >> p;
cout << "输入链表要存入数字数量" << endl;
cin >> q;
y.assign(q, p);
printlist(y);
list<int>v;
v = a;
printlist(v);
cout << "a为" << endl;
printlist(a);
cout << "y为" << endl;
printlist(y);
a.swap(y);
cout << "a为" << endl;
printlist(a);
cout << "y为" << endl;
printlist(y);
system("pause");
return 0;
}
list容器大小操作
功能描述:
-
对list容器和大小进行操作
#include<iostream>
#include<list>
using namespace std;
void printlist(list<int>a)
{
for (list<int>::iterator it = a.begin(); it != a.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
list<int>a;
int b;
cout << "输入要存入的数量" << endl;
cin >> b;
for (int i = 0; i < b; i++)
{
int g;
cout << "输入要存入的数字" << endl;
cin >> g;
a.push_back(g);
}
printlist(a);
if (a.empty())
{
cout << "这是一个空容器" << endl;
}
else
{
cout << "容器不为空" << endl;
cout << "容器大小为" <<a.size()<< endl;
}
a.resize(10, 2);
printlist(a);
a.resize(2);
printlist(a);
system("pause");
return 0;
}
list容器插入和删除
功能描述:
-
对list容器进行数据的插入和删除
#include<iostream>
#include<list>
using namespace std;
void printlist(list<int>a)
{
for (list<int>::iterator it = a.begin(); it != a.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void push(list<int>&a)
{
int b;
cout << "输入要存入的数量" << endl;
cin >> b;
for (int i = 0; i < b; i++)
{
int g;
cout << "输入要存入的数字" << endl;
cin >> g;
a.push_back(g);
}
}
void pushback(list<int>&a) //尾插法插入
{
int b;
cout << "输入要存入的数据" << endl;
cin >> b;
for (int i; i < b; i++)
{
int y;
cout << "输入要存入的数据" << endl;
cin >> y;
a.push_back(y);
}
}
void pushfront(list<int>& a) //头插法插入
{
int b;
cout << "输入要存入的数据" << endl;
cin >> b;
for (int i; i < b; i++)
{
int y;
cout << "输入要存入的数据" << endl;
cin >> y;
a.push_front(y);
}
}
void deleteback1(list<int>&a) //尾删法
{
int b;
cout << "输入要删除的数据" << endl;
cin >> b;
for (int i; i < b; i++)
{
a.pop_back();
}
}
void deleteback2(list<int>& a) //头删法
{
int b;
cout << "输入要删除的数据" << endl;
cin >> b;
for (int i; i < b; i++)
{
a.pop_front();
}
}
void add(list<int>&a) //在指定位置插入
{
int b;
int c;
int d;
cout << "输入要存入的数据的量" << endl;
cin >> b;
//cout << "输入要存入数据的位置(头部开始计数)" << endl;
//cin >> c;
cout << "输入要存入的数据" << endl;
cin >> d;
a.insert(a.begin (), d); //可以a.gegin()++ 但是不能c+a.和 a.+c导致无法控制
printlist(a);
a.insert(a.begin(), b, d);
printlist(a);
}
int main()
{
list<int>a;
push(a);
printlist(a);
pushback(a);
printlist(a);
pushfront(a);
printlist(a);
add(a);
list<int>b;
b.insert(b.begin(), a.begin(), a.end());
printlist(b);
deleteback2(a);
printlist(a);
deleteback1(a);
printlist(a);
a.erase(a.begin());
printlist(a);
a.erase(a.begin(), a.end());
printlist(a);
list<int>c;
c = b;
b.clear();
printlist(b);
int n;
cout << "输入要删除的数字" << endl;
cin >> n;
c.remove(n); //所有的n都删除
printlist(c);
cout << c.front() << endl;
cout << c.back() << endl;
system("pause");
return 0;
}
list容器数据存取
功能描述:
-
对list容器中数据进行存取
注意事项
-
list<int>a; a[0]不可以用[]访问list容器中的元素
-
a.at(0);不可以用at方式访问list容器中的元素
-
list本质是链表,不是用连续线性空间存储数据(所以不能通过加整形跳位)迭代器也是不支持随机访问的
cout << c.front() << endl; cout << c.back() << endl;
判断方式
支持++ --为双向迭代器
支持+n为课跳跃迭代器(支持随机访问)
只支持++为单向
list容器反转和排序
功能描述:
-
将容器中的元素反转,以及将容器中的数据进行排序
注意事项:
-
所有不支持随机访问迭代器的容器,不可以用标准算法
-
不支持随机访问迭代器的容器,内部会提供对应的一些算法
-
默认排序规则从小到大
-
大到小
bool mycompare(int a, int b)
{
return a > b;
}
a.sort(mycompare);
#include<iostream>
#include<list>
#include<algorithm>
using namespace std;
void printlist(list<int>a)
{
for (list<int>::iterator it = a.begin(); it != a.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void pushback(list<int>&a)
{
int b;
cout << "输入要存入链表的数据的量" << endl;
cin >> b;
for(int i=0;i<b;i++)
{
int d;
cout << "输入要存入的数字" << endl;
cin >> d;
a.push_back(d);
}
}
void popback(list<int>&a)
{
int b;
int c;
cout << "输入要删除的数量" << endl;
cin >> b;
for (int i = 0; i < b; i++)
{
a.pop_back();
}
}
bool mycompare(int a, int b)
{
return a > b;
}
//对应类的
bool mycompare2(类名 &a ,类名&b)
{
if(a.类内成员1==a.类内成员1)
{
return a.类内成员2<b.类内成员2;
}
else
{
return a.类内成员1<b.类内成员1;
}
}
int main()
{
list<int>a;
pushback(a);
printlist(a);
a.reverse();
printlist(a);
a.sort(mycompare);//类的同理调用
printlist(a);
system("pause");
return 0;
}