🔥个人主页:guoguoqiang. 🔥专栏:我与C++的爱恋
一、list介绍
1.list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代
2.list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素
3.list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效
4.与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好
5.与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置 (比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息 (对于存储类型较小元素的大list来说这可能是一个重要的因素)
list可以双向迭代,本质就是双向循环链表
二、接口函数
构造函数
1.默认构造函数创建一个没有任何元素的空链表。
2.填充构造函数允许创建一个包含特定数量相同值的元素的链表。
3.范围构造函数可以从任何提供迭代器接口的其他容器复制元素。
4.拷贝构造函数创建了一个当前list的副本。
填充构造函数前面的explicit关键字表明这个构造函数不能用于隐式转换或复制初始化,它需要直接调用来构造对象。其他构造函数则根据是否带有explicit关键字来决定是否能用于隐式转换或复制初始化
迭代器
迭代器用来遍历链表。
int main() {list<int> it = { 1,2,3,4,5,6,10 };list<int>::iterator i1 = it.begin();while (i1 != it.end()) {cout << *i1 << " ";i1++;}cout << endl;for (auto e : it) {cout << e << " ";}cout << endl;return 0;
}
容量操作
empty检测list是否为空,是返回true,否则返回false
size返回有效元素个数的值
元素访问
front返回list的第一个节点值的引用
back返回list的最后一个节点值的引用
内容操作
insert在这里不会出现迭代器失效
迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响
void TestListIterator1()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));auto it = l.begin();while (it != l.end()){l.erase(it);++it;}
}
erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给其赋值
void TestListIterator()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));auto it = l.begin();while (it != l.end()){it = l.erase(it);//这行代码就在删除后更新了it}
}
在list中erase失效只影响被删除的元素,但是对于其他的容器(vector、deque)可能就不能这样了,因为这些容器的erase操作可能会影响被删除的元素之后的元素的迭代器全部失效。
operations
list 提供了一些有用的成员函数,允许执行各种操作,如元素的合并、移除、排序和倒序。
1.splice: 将元素从一个列表转移到另一个列表,可以转移整个列表、一个单独的元素或一个元素范围。
int main() {list<int> list1 = { 1, 2, 3 };list<int> list2 = { 4, 5, 6 };list1.splice(list1.end(), list2);list<int>::iterator i1 = list1.begin();while (i1 != list1.end()) {cout << *i1 << " ";i1++;}cout << endl;//1 2 3 4 5 6return 0;
}
2.remove: 从列表中移除所有具有特定值的元素。
int main() {list<int> list1 = { 1, 2, 3,3,3,5,6 };list1.remove(3);list<int>::iterator i1 = list1.begin();while (i1 != list1.end()) {cout << *i1 << " ";i1++;}cout << endl;//1 2 5 6return 0;
}
3.remove_if: 根据一个判断条件移除元素。
int main() {list<int> list1 = { 1, 2, 3,3,3,5,6 };list1.remove_if([](int n) { return n % 2 == 0; });list<int>::iterator i1 = list1.begin();while (i1 != list1.end()) {cout << *i1 << " ";i1++;}cout << endl;return 0;
}
4.unique: 移除连续并且重复的元素,只保留唯一的元素。
int main() {list<int> list1 = { 1, 2, 3,3,3,5,5,6,6,8,9 };list1.unique();list<int>::iterator i1 = list1.begin();while (i1 != list1.end()) {cout << *i1 << " ";i1++;}cout << endl;return 0;
}
5.merge: 合并两个已排序的列表,并确保结果列表也是排序的。
int main() {std::list<int> list1 = { 1, 3, 5 };std::list<int> list2 = { 2, 4, 6 };list1.merge(list2);list<int>::iterator i1 = list1.begin();while (i1 != list1.end()) {cout << *i1 << " ";i1++;}cout << endl;return 0;
}
6.sort: 对列表中的元素进行排序。它接受一个比较函数作为参数(可选)。
int main() {std::list<int> list1 = { 4, 3, 5, 2, 1 };list1.sort();list<int>::iterator i1 = list1.begin();while (i1 != list1.end()) {cout << *i1 << " ";i1++;}cout << endl;return 0;
}
7.reverse: 反转列表中元素的顺序。
int main() {std::list<int> list1 = { 5,4, 3, 2, 1 };list1.reverse();list<int>::iterator i1 = list1.begin();while (i1 != list1.end()) {cout << *i1 << " ";i1++;}cout << endl;return 0;
}
本篇内容到此结束,感谢大家的观看!!!