手机网站建设信息织梦网站怎样做子域名

当前位置: 首页 > news >正文

手机网站建设信息,织梦网站怎样做子域名,seo查询官网,沈阳网站推广排名方案目录 一#xff1a;介绍二#xff1a;list的创建和方法创建list方法 三#xff1a;list的具体用法3.1 push_back、pop_back、push_front、pop_front3.2 insert() 和 erase()3.3 splice 函数 四#xff1a;list容器底层实现4.1 list 容器节点结构5.2 list容器迭代器的底层实… 目录 一介绍二list的创建和方法创建list方法 三list的具体用法3.1 push_back、pop_back、push_front、pop_front3.2 insert() 和 erase()3.3 splice 函数 四list容器底层实现4.1 list 容器节点结构5.2 list容器迭代器的底层实现5.2 list容器的主体实现 总结 对2024年航空航天与力学国际学术会议ICAM 2024 感兴趣的伙伴可以点击【click】 一介绍 list是一种序列式容器。该容器的底层是用双向链表实现的, 在链表的任一位置进行元素的插入、删除操作都是快速的。 二list的创建和方法 首先使用vector时需包含头文件 #include list 创建list list本质是类模板可以存储任何类型的数据。数组在声明前需要加上数据类型而list则通过模板参量设定类型。 比如声明一个int型的list列表。 listA listname; // 一个空列表listA listname(size); // 开辟size个空间值默认为0listA listname(size, value); // size个值为value的数组listA listname(elselist); // 拷贝构造参数是其他listlistA listname(first, last); // 迭代器初始化 方法 ✨iterators迭代器 \colorbox{pink}{✨iterators迭代器} ✨iterators迭代器​ 名字描述begin返回指向容器中第一个元素的迭代器。end返回指向容器最后一个元素所在位置后一个位置的迭代器rbegin返回容器逆序的第一个元素的迭代器rend返回容器逆序的最后一个元素的前一个位置的迭代器cbegin和begin()功能相同在其基础上增加了 const 属性不能用于修改元素。cend和end()功能相同在其基础上增加了 const 属性不能用于修改元素。crbegin和rbegin()功能相同在其基础上增加了 const 属性不能用于修改元素。crend和rend()功能相同在其基础上增加了 const 属性不能用于修改元素。 ✨Capacity容量 \colorbox{pink}{✨Capacity容量} ✨Capacity容量​ 名字描述size返回实际元素的个数empty判断list是否为空为空返回true否则falsemax_size返回元素个数的最大值。 ✨Element access元素访问 \colorbox{pink}{✨Element access元素访问} ✨Element access元素访问​ 名字描述front返回第一个元素back返回最后一个元素 ✨Modifiers修改器 \colorbox{pink}{✨Modifiers修改器} ✨Modifiers修改器​ 名字描述push_back在容器的尾部插入元素pop_back删除最后一个元素push_front在容器的头部插入元素pop_front删除第一个元素erase删除元素clear清除容器内容size0存储空间不变swap交换两个元素的所有内容assign用新元素替换原有内容。emplace_front插入元素和insert实现原理不同速度更快emplace_back在容器的尾部插入元素和push_back不同, 速度更快 三list的具体用法 3.1 push_back、pop_back、push_front、pop_front listint lt1; for (int i 0; i 5; i) {lt1.push_back(i);lt1.push_front(i); } for (int i 0; i 5; i) {lt1.pop_back();lt1.pop_front(); } emplace_back的效果和push_back一样具体可以查看前一篇vector的博客 3.2 insert() 和 erase() insert()在指定位置插入一个或多个元素(三个重载) l1.insert(l1.begin(), 100); 在l1的开始位置插入100。l1.insert(l1.begin(), 2, 200); 在l1的开始位置插入2个100。l1.insert(l1.begin(), l2.begin(), l2.end()); 在l1的开始位置插入l2的从开始到结束的所有位置的元素。erase()删除一个元素或一个区域的元素(两个重载) l1.erase(l1.begin()); 将l1的第一个元素删除。l1.erase(l1.begin(), l1.end()); 将l1的从 begin() 到 end() 之间的元素删除。3.3 splice 函数 splice函数是list中的一个转移函数将另外一个list中的元素转移到本list中。共有3个重载 1、list1.splice(position, list2): 将list2中的所有元素剪贴到list1的position位置 2、list1.splice(position, list2, iter): 将list2中某个位置的迭代器iter指向的元素剪贴到list1中的position位置 3、list1.splice(position, list2, iter1, iter2): 将list2中的某一段位置iter1 ~ iter2的元素剪贴到list1中的position位置 void list_splice() {listintmylist1, mylist2;for (int i 1; i 4; i) mylist1.push_back(i);for (int i 1; i 4; i) mylist2.push_back(i * 10);std::listint::iterator it1 mylist1.begin();it1;mylist1.splice(it1, mylist2); // 转移mylist2到it1位置之前// 注意此时链表2就为空链表了 所以splice名字叫做转移for (auto e : mylist1){cout e ;} }// 输出1 10 20 30 40 2 3 4四list容器底层实现 容器的底层是用双向链表实现的甚至一些 STL 版本中比如 SGI STLlist 容器的底层实现使用的是双向循环链表。 头指针使用链表存储数据并不会将它们存储到一整块连续的内存空间中。恰恰相反各元素占用的存储空间又称为节点是独立的、分散的它们之间的线性关系通过指针来维持。 4.1 list 容器节点结构 双向链表的各个节点中存储的不仅仅是元素的值还应包含 2 个指针分别指向前一个元素和后一个元素。 templateclass T
struct ListNode // 当一个类不想要访问限定符限制的时候就用struct {ListNode* _next;ListNode* _prev;T _data;ListNode(const T data):_next(nullptr), _prev(nullptr), _data(data){} };注为了方便阅读和理解本文章所实现的list都省略了与本文核心内容不相关的内容如果读者对此部分感兴趣可查看 list 容器实现源码。 本人的 gitee上具有本文实现的完整代码及测试代码需要的可以自取【click】 5.2 list容器迭代器的底层实现 和 vector 这些容器迭代器的实现方式不同由于 list 容器的元素并不是连续存储的所以该容器迭代器中必须包含一个可以指向 list 容器的指针并且该指针还可以借助重载的 、、–、、! 等运算符实现迭代器正确的递增、递减、取值等操作。 所以我们就需要对迭代器进行封装 可以看到迭代器的移动就是通过操作节点的指针实现的。 注意因为存在const迭代器 和 非const迭代器 所以这里我们的模版参数有三个一个为存储类型 一个为 引用返回类型 一个为 指针类型const 和 非const // 通过模板给不同的模板参数让编译器帮我们实例化两个类 templateclass T, class Ref, class Ptr struct ListIterator {typedef ListNodeT Node;typedef ListIteratorT, Ref, Ptr Self;Node _node;ListIterator(Node* node):_node(node){}Self operator() // 迭代器返回自己 所以typedef一下{_node _node-_next;return *this;}Self operator(int) // 后置 不能用引用返回了 tmp会销毁{Self tmp(*this); // 默认的拷贝构造_node _node-_next;return tmp;}Self operator–(){_node _node-_prev;return *this;}Self operator–(int) // 后置–{Self tmp(this);_node _node-_prev;return tmp;}Ptr operator-(){return _node-_data;}Ref operator(){return _node-_data;}bool operator!(const Self it){return _node ! it._node;}bool operator(const Self it){return _node it._node;} };接下来是reverse_iterator的实现 注意反向迭代器的实现可以对正向迭代器进行复用 具体代码如下 // 此处的参数就是正向迭代器了 templateclass iterator, class Ref, class Ptr struct Reverse_ListIterator {typedef Reverse_ListIteratoriterator, Ref, Ptr Self;iterator _it;Reverse_ListIterator(iterator it):_it(it){}Ref operator*(){iterator tmp _it;return tmp._node-_prev;}// 作用是为pos这种结构体服务的Ptr operator-(){return _it._node-_prev-_data;}Self operator(){_it._node _it._node-_prev;return *this;}Self operator(int){Self tmp(*this);_it._node _it._node-_prev;return tmp;}Self operator–(){_it._node _it._node-_next;return *this;}Self operator–(int){Self tmp(*this);_it._node _it._node-_next;return tmp;}bool operator!(const Self it){return _it._node ! it._it._node; // 复用的结果}bool operator(const Self it){return _it._node it._node;}};5.2 list容器的主体实现 以下是主体实现 templateclass T class list {typedef ListNodeT Node;// 不符合迭代器的行为无法遍历 无法进行和操作 所以我们要将迭代器封装成一个类进行运算符重载即可// typedef Node iterator; public:typedef ListIteratorT, T, T* iterator; //规范迭代器typedef ListIteratorT, const T, const T* const_iterator; // 通过模板给不同的模板参数让编译器帮我们实例化两个类// list的const迭代器是有东西的typedef Reverse_ListIteratoriterator, T, T* reverse_iterator;typedef Reverse_ListIteratorconst_iterator, const T, const T* const_reverse_iterator;iterator begin(){return iterator(_head-_next); // 匿名对象}iterator end(){return iterator(_head);}const_iterator begin() const{return const_iterator(_head-_next); // 匿名对象}const_iterator end() const{return const_iterator(_head);}reverse_iterator rbegin(){return reverse_iterator(end()); // 匿名对象}reverse_iterator rend(){return reverse_iterator(begin());}list() // 初始化哨兵卫的头节点{_head new Node(T()); // 没有合适的默认构造函数可用 这里用匿名对象初始化_head-_next _head;_head-_prev _head;}void empty_init(){_head new Node(T());_head-_next _head;_head-_prev _head;}list(const listT lt){empty_init();for (const auto e : lt){push_back(e);}}// 这里的赋值重载是现代写法listT operator(listT lt){swap(_head, lt._head);return this;}~list(){clear();delete _head;}void push_back(const T x){Node newnode new Node(x); // 就不需要专门写个CreatNewNode的了 自动调用Node的构造函数/newnode-_next _head;newnode-_prev _head-_prev;_head-_prev-_next newnode;_head-_prev newnode;/insert(end(), x);}iterator insert(iterator pos, const T x){Node* node new Node(x);Node* cur pos._node;Node* prev cur-_prev;node-_next cur;node-_prev prev;prev-_next node;cur-_prev node;return iterator(node);}iterator erase(iterator pos){assert(pos ! end());Node* cur pos._node;Node* prev cur-_prev;Node* next cur-_next;prev-_next next;next-_prev prev;delete cur;return iterator(next);}void pop_back(){erase(–end());}void push_front(const T x){insert(begin(), x);}void pop_front(){erase(begin());}void clear(){listT::iterator it begin();while (it ! end()){it erase(it);}}private:Node* _head; };总结 list的详细用法和底层实现就介绍到这里了如果有任何疑问都可以私信我希望我们共同进步 有错误还请在评论区指正