济南做网站找哪家好,微信小程序免费模板直接套用,常州网站开发公司,聊天室网站开发#x1f31f;快来参与讨论#x1f4ac;#xff0c;点赞#x1f44d;、收藏⭐、分享#x1f4e4;#xff0c;共创活力社区。 #x1f31f; 如果你对string#xff0c;vector还存在疑惑#xff0c;欢迎阅读我之前的作品 #xff1a; 之前文章#x1f525;#x1… 快来参与讨论点赞、收藏⭐、分享共创活力社区。 如果你对stringvector还存在疑惑欢迎阅读我之前的作品 之前文章 【C】vector 类深度解析探索动态数组的奥秘 【C】string 类深度解析探秘字符串操作的核心 目录
前言
为什么要学习 list 类
一高效的插入和删除操作
二灵活的内存管理
三迭代器稳定性
标准库中的 list 类
一定义与头文件
list 类的内部结构
一节点结构
二内存布局
list 类的构造函数
一默认构造函数
二带参数的构造函数
list 类的成员函数
一获取链表信息的函数
二链表修改函数✍️
三获取特定元素的函数
四链表查找函数
list 类的操作符重载
一赋值操作符
二下标操作符[]
总结 前言 嘿小伙伴们在 C 编程的奇妙旅程中我们经常会碰到各种数据结构的难题。今天咱们就来好好研究一下 C 标准库中的 list 类它就像一个超级厉害的双向链表小助手能帮我们轻松搞定很多复杂的任务哦当我们需要频繁地在数据序列中插入和删除元素时list 类可是个绝佳的选择呢它比传统数组灵活多啦不会因为插入或删除一个元素就把其他元素弄得乱七八糟。想知道它为什么这么神奇吗那就接着往下看吧 相关资料list文档介绍 为什么要学习 list 类
一高效的插入和删除操作 想象一下你有一排小玩偶想要在中间插入一个新的玩偶或者拿走一个玩偶。如果它们是像传统数组那样紧紧挨在一起排列的每次插入或拿走一个玩偶都得把后面的玩偶一个一个地挪动位置是不是超级麻烦但是如果这些玩偶是用一种特殊的方式连接起来的就像 list 类中的双向链表一样每个玩偶都有两条 “小绳子”一条连着前面的玩偶一条连着后面的玩偶。当你要插入或拿走一个玩偶时只需要解开和系上相应的 “小绳子” 就可以啦是不是简单多了这就是 list 类在插入和删除元素时的厉害之处哦无论在链表的哪个位置进行操作它都能快速完成时间复杂度是常数级别呢对于那些经常需要修改数据顺序的程序来说它简直就是一个神器
二灵活的内存管理 list 类的内存管理就像搭积木一样有趣又灵活每个元素就像是一块单独的积木它们不需要紧紧地靠在一起可以分散在内存的各个地方。当你需要添加或删除一个元素时就像拿走或添加一块积木不会影响其他积木的位置哦。这种方式避免了因为内存碎片而导致的性能问题能让你的程序更好地利用内存资源是不是很棒呢
三迭代器稳定性 迭代器就像是一个小小的导航员用来在 list 中逐个访问元素。在 list 中当你插入或删除一个元素时除了指向被操作元素的迭代器会失效因为这个元素被改变了嘛其他迭代器就像坚固的小灯塔一样依然稳稳地指向它们原来的元素哦这在我们需要一边遍历 list一边进行插入或删除操作时特别有用不用担心因为操作一个元素而导致其他元素找不到了程序可以稳稳地运行下去是不是很让人安心呢 标准库中的 list 类
一定义与头文件 list 类住在 C 标准库的list头文件里哦。就像我们要去一个神秘的地方需要知道地址一样想要使用 list 类就得先包含这个头文件然后加上using namespace std;这句话这样我们就能在程序里使用 list 类提供的各种神奇功能啦
#include iostream
#include listusing namespace std; list 类的内部结构
一节点结构 list 类内部是由一个个节点组成的每个节点就像一个小小的魔法盒子里面装着三个重要的东西呢首先是真正的数据元素就像魔法盒子里的宝藏一样然后是一个指向前面节点的指针就像魔法盒子前面的小钩子可以勾住前面的节点还有一个指向后面节点的指针就像魔法盒子后面的小尾巴可以连接后面的节点。通过这些指针节点们就像手拉手的好朋友一样形成了一个双向链表我们可以从前往后或者从后往前遍历哦是不是很有趣
二内存布局 节点们在内存里就像一群自由自在的小精灵♂️♀️它们不需要站在连续的位置上。每个节点根据自己的需要在内存中找到一个合适的地方安家。当我们要插入或删除一个节点时就像小精灵飞进或飞出它们的群体一样只需要调整相关节点的指针不需要像数组那样大规模地移动元素所以操作起来速度很快哦 list 类的构造函数
一默认构造函数 list 类的默认构造函数就像一个神奇的魔法咒语✨念一下就能创建一个空的 list 对象这个时候 list 里面什么元素都没有就像一个空的魔法盒子一样。例如 二带参数的构造函数 使用迭代器区间构造 我们还可以用迭代器区间来创建 list 对象哦比如说我们有一个其他容器像 vector里的一段元素想把它们放到 list 里就可以用迭代器指定这个区间然后 list 就会把这段区间里的元素一个一个复制过来就像把一群小蚂蚁从一个地方搬到另一个地方一样。例如
#include iostream
#include list
#include vectorusing namespace std;int main() {vectorint v {1, 2, 3, 4, 5};listint l(v.begin(), v.end());cout 使用迭代器区间构造的list对象的大小为: l.size() endl;return 0;
} 指定数量和初始值构造 另外我们也可以指定要创建的 list 对象里元素的数量让它们都用默认值初始化或者直接指定数量和初始值。就像我们要订做一批小蛋糕可以告诉面包师做几个是都做成普通口味默认值还是都做成巧克力口味指定初始值。例如
#include iostream
#include listusing namespace std;int main() {listint l1(5); // 创建包含5个默认初始化元素的listcout 使用指定数量默认初始化构造的list对象l1的大小为: l1.size() endl;listint l2(3, 10); // 创建包含3个值为10的元素的listcout 使用指定数量和初始值构造的list对象l2的大小为: l2.size() endl;return 0;
} list 类的成员函数
一获取链表信息的函数 size()函数size()函数就像一个小计数器它能准确地返回 list 中当前元素的个数。例如 #include iostream
#include listusing namespace std;int main() {listint l {1, 2, 3, 4, 5};cout list中的元素个数为: l.size() endl;return 0;
} empty()函数empty()函数则像一个小检查员用来检测 list 是否为空。如果 list 里面没有元素它就会返回true就像告诉你 “这个盒子是空的哦”如果有元素就返回false。例如 #include iostream
#include listusing namespace std;int main() {listint l1;cout list1是否为空: (l1.empty() ? 是 : 否) endl;listint l2 { 1 };cout list2是否为空: (l2.empty() ? 是 : 否) endl;return 0;
} 二链表修改函数✍️ push_front()函数push_front()函数就像一个热情的小主人总是在 list 的开头添加新元素。例如 #include iostream
#include listusing namespace std;int main() {listint l;l.push_front(5);l.push_front(3);l.push_front(1);for (int i : l) {cout i ;}cout endl;return 0;
} push_back()函数push_back()函数则像一个贴心的小尾巴在 list 的末尾添加元素。例如 #include iostream
#include listusing namespace std;int main() {listint l;l.push_back(1);l.push_back(3);l.push_back(5);for (int i : l) {cout i ;}cout endl;return 0;
} pop_front()函数pop_front()函数就像一个勇敢的小先锋从 list 的开头删除元素。例如 #include iostream
#include listusing namespace std;int main() {listint l {1, 2, 3, 4, 5};l.pop_front();for (int i : l) {cout i ;}cout endl;return 0;
} pop_back()函数pop_back()函数像一个安静的小后卫从 list 的末尾删除元素。例如 #include iostream
#include listusing namespace std;int main() {listint l {1, 2, 3, 4, 5};l.pop_back();for (int i : l) {cout i ;}cout endl;return 0;
} insert()函数insert()函数是一个多功能的小工匠它可以在指定位置插入一个或多个元素。例如 #include iostream
#include listusing namespace std;int main() {listint l {1, 3, 4, 5};auto it l.begin();it;l.insert(it, 2);for (int i : l) {cout i ;}cout endl;return 0;
} erase()函数erase()函数像一个精准的小剪刀✂️可以删除 list 中的指定元素或元素区间。例如 #include iostream
#include listusing namespace std;int main() {listint l {1, 2, 3, 4, 5};auto it l.begin();it;l.erase(it);for (int i : l) {cout i ;}cout endl;return 0;
} 三获取特定元素的函数 front()函数front()函数就像一个小探险家♂️总是能快速找到 list 中的第一个元素并返回它。例如 #include iostream
#include listusing namespace std;int main() {listint l {1, 2, 3, 4, 5};cout list中的第一个元素为: l.front() endl;return 0;
} back()函数back()函数则像一个小后卫♂️负责返回 list 中的最后一个元素。例如 #include iostream
#include listusing namespace std;int main() {listint l {1, 2, 3, 4, 5};cout list中的最后一个元素为: l.back() endl;return 0;
} 四链表查找函数 在 list 中查找元素可以使用find()算法结合 list 的迭代器。就像在一个宝藏迷宫里寻找特定的宝物一样我们可以通过迭代器逐个比较元素来找到我们想要的元素。例如
#include iostream
#include list
#include algorithmusing namespace std;int main() {listint l {1, 2, 3, 4, 5};auto it find(l.begin(), l.end(), 3);if (it! l.end()) {cout 找到元素的位置为: distance(l.begin(), it) endl;} else {cout 未找到元素 endl;}return 0;
} list 类的操作符重载
一赋值操作符 list 类重载了赋值操作符就像一个神奇的复制魔法可以将一个 list 对象的值复制给另一个 list 对象。例如
#include iostream
#include listusing namespace std;int main() {listint l1 {1, 2, 3};listint l2;l2 l1;for (int i : l2) {cout i ;}cout endl;return 0;
}
二下标操作符[] 虽然 list 类本身没有像 vector 那样直接支持下标操作符重载但我们可以通过迭代器来模拟类似的功能。例如
#include iostream
#include listusing namespace std;int main() {listint l {1, 2, 3, 4, 5};auto it l.begin();advance(it, 2); // 将迭代器移动到第三个元素位置cout 第三个元素的值为: *it endl;return 0;
} 总结 哇哦C 的 list 类真的是一个非常强大且有趣的双向链表工具呢它的内部结构、构造函数、成员函数和操作符重载等特性让我们在处理动态数据序列时更加得心应手。通过深入理解 list 类我们可以更好地应对各种编程挑战提高程序的灵活性和效率。在实际编程中我们要根据具体需求合理选择使用 list 类充分发挥它的优势避免一些常见的错误哦。希望小伙伴们在 C 的编程世界里继续探索发现更多的乐趣和惊喜 期待下次与你们分享更多精彩内容哦欢迎关注我【A Charmer】