功能:将数据进行链式存储
链表是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的
链表组成:链表是由一系列结点组成
结点的组成:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域
STL中的链表是一个双向循环链表
由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器
list的优点:
采用动态存储分配,不会造成内存浪费和溢出
链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
list的缺点
链表灵活,但是空间(指针域)和时间(遍历)额外耗费较大,
list有一个重要的诶性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的
总结:STL中list和vector是两个常用的容器
1.构造函数
list list;//list采用模板类实现,list对象的默认构造形式
list(beg,end)😕/构造函数将区间内的元素拷贝给本身
list(n,elem)😕/
list(const list &list)//拷贝构造函数
2.赋值和交换
和之前的容器一样
assign(beg,end); //将区间内的数据拷贝赋值给本身
assign(n,elem)//
swap(list)//将list与本身的元素互换
3.大小操作:
和之前容器一样
size()
empty()
resize()
4.插入和删除
push_back(elem);
pop_back();
push_front():
从字面可以看出这个函数和push_back相反,它是在容器开头增加新的元素,因为容器特性的原因,有些不支持这个操作,比如vector,vector类似于数组,而数组是没法直接在原来的内存空间前面再插入一块新的空间用于存储新的元素,而list则支持这个操作,list相当于链表,链表通过指针指向不同的内存空间并连接在一起,可以实现这种操作。如下:
list<int> lt;
lt.push_front(1);
lt.push_front(2);
lt.push_front(3);
这样插入过后,lt内部元素按照顺序就是3,2,1,因为是从头部插入数据,所以后插入的在前面。相当于链表的头插法操作。
pop_front()
insert()
clear()
erase()
remove(elem)//删除容器中所有与elem值匹配的元素
5.数据存取
front():返回第一个元素
back():返回最后一个元素
6.反转和排序
sort()//链表排序
reverse()//反转链表
//反转和排序
void printlist(list<int>L) {
for (list<int>::iterator it = L.begin(); it != L.end(); it++) {
cout << *it << endl;
}
}
void test01() {
list<int> list1;
list1.push_back(20);
list1.push_back(10);
list1.push_back(50);
list1.push_back(40);
list1.push_back(30);
printlist(list1);
list1.reverse();
}
//排序
void test02() {
list<int> list1;
list1.push_back(20);
list1.push_back(10);
list1.push_back(50);
list1.push_back(40);
list1.push_back(30);
printlist(list1);
sort(list1.begin(), list1.end());//会报错,因为所有不支持随机访问迭代器的容器,不可以用标准算法
//不支持随机访问迭代器的容器,内部会提供对应一些算法
list1.sort();//sort是成员函数不是全局函数
}