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

ps网站参考线怎么做百度推广如何办理

ps网站参考线怎么做,百度推广如何办理,wordpress版本查看,wordpress know how博主首页: 有趣的中国人 专栏首页: C专栏 本篇文章主要讲解 list模拟实现的相关内容 1. list简介 列表(list)是C标准模板库(STL)中的一个容器,它是一个双向链表数据结构&#xff0c…
图片名称

博主首页: 有趣的中国人

专栏首页: C++专栏


    本篇文章主要讲解 list模拟实现的相关内容

    1. list简介


    列表(list)C++标准模板库(STL)中的一个容器,它是一个双向链表数据结构,用于存储元素。与vector不同,列表中的元素在内存中不是连续存储的,而是通过指针相互连接形成链表。这种设计使得列表对于插入和删除操作非常高效,但是在查找特定元素时相对较慢,因为需要按序遍历整个链表。


      2. list模拟实现

      2.1 list类的相关成员变量

      C++的标准库中,list的实现方式是带头双向循环链表,因此在类中,我们需要一个头指针_head。至于每个节点,我们也同样需要构造一个类,其中成员变量包含_prev_next和数据_val

      template<class T>
      struct ListNode
      {ListNode<T>* _prev;ListNode<T>* _next;T _val;ListNode(const T& x = T()):_prev(nullptr),_next(nullptr),_val(x){}
      };
      template<class T>
      class list
      {
      public:typedef ListNode<T> Node;list(){_head = new Node;_head->_prev = _head;_head->_next = _head;}
      private:Node* _head;
      };
      

        2.2 尾插

        尾插太简单了,直接上代码:

        void push_back(const T& x)
        {Node* newnode = new Node(x);Node* tail = _head->_prev;tail->_next = newnode;newnode->_prev = tail;newnode->_next = _head;_head->_prev = newnode;
        }
        

          2.3 迭代器

          在库中,我们不管迭代器的底层是如何实现的,但是我们都要用相同的方法使用迭代器,例如之前讲过的 vectorstring,在g++中的实现方法就是原生指针,来实现例如++--等功能,但是这里list由于不是连续存储的,所以用原生指针正常的++--等功能并不能达到我们的预期,因此我们可以把迭代器搞成一个类类型,并用运算符重载来改变它的功能。

          下面的代码是迭代器正常的使用方法,我们需要用运算符重载来实现这些功能:
          void list_test1()
          {list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;
          }
          

            2.3.1 迭代器类的成员变量

            迭代器类中其实就包含了一个指向结点类型的指针,因为我们的目的就是改变原生指针的相关操作,来实现迭代器相关的操作。
            代码如下:

            struct ListNodeIterator
            {typedef ListNode<T> Node;Node* _node;ListNodeIterator(Node* node):_node(node){}
            };
            

              2.3.2 迭代器类的实现

              template<class T>
              struct ListNodeIterator
              {typedef ListNode<T> Node;typedef ListNodeIterator<T> Self;Node* _node;ListNodeIterator(Node* node):_node(node){}T& operator*(){return _node->_val;}Self& operator++(){_node = _node->_next;return *this;}Self operator++(int){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;}bool operator!=(const Self& it){return _node != it._node;}
              };
              

                2.3.3 insert 和 erase

                inserterase传的参数就是iterator,模拟实现代码如下:

                void insert(iterator pos, const T& x)
                {Node* newnode = new Node(x);Node* cur = pos._node;Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;
                }
                void erase(iterator pos)
                {Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;cur = nullptr;
                }
                
                这里需要注意,在erase的时候由于迭代器指向的空间被释放了,会导致迭代器失效的问题,之前的文章讲过相关的内容,因此我们需要更新iterator,指向被删除的位置的下一个位置即可,代码如下:
                iterator erase(iterator pos)
                {Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;cur = nullptr;return next;
                }
                

                  2.3.4 begin 和 end

                  beginend是在迭代器中的成员函数,返回头和尾的迭代器即可:

                  typedef ListNodeIterator<T> iterator;
                  iterator begin()
                  {return iterator(_head->_next);// 单参数类型的构造函数支持隐式类型转换,以下依法也可以:// return _head->_next;
                  }
                  iterator end()
                  {return iterator(_head);// return _head;
                  }
                  

                    2.3.5 insert 和 erase的复用

                    push_backpush_frontpop_backpop_front都可以复用inserterase,代码如下:

                    void push_back(const T& x)
                    {/*Node* newnode = new Node(x);Node* tail = _head->_prev;tail->_next = newnode;newnode->_prev = tail;newnode->_next = _head;_head->_prev = newnode;*/insert(end(), x);
                    }
                    void pop_back()
                    {erase(--end());
                    }
                    void push_front(const T& x)
                    {insert(begin(), x);
                    }
                    void pop_front()
                    {erase(begin());
                    }
                    

                    测试代码:

                    void list_test1()
                    {list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;lt.pop_back();lt.pop_back();it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;lt.push_front(100);lt.push_front(200);lt.push_front(300);it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;lt.pop_front();lt.pop_front();it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;
                    }
                    

                    在这里插入图片描述


                      2.3.5 operator->的重载

                      • 先看一下这段代码:
                      void list_test2()
                      {struct A{int _a1;int _a2;A(int a1 = 0, int a2 = 0):_a1(a1),_a2(a2){}};list<A> lt;A a(1, 2);lt.push_back(a);lt.push_back(A(3, 4));lt.push_back({ 5,6 });list<A>::iterator it = lt.begin();while (it != lt.end()){// 主要看这里cout << (*it)._a1 << " " << (*it)._a2 << " ";cout << endl;++it;}
                      }
                      

                      我们注意到当我们访问自定义类型的数据需要这样:(*it)._a1进行访问,但是迭代器就是为了模仿指针的相关操作,例如我们有A*这种类型的指针如何进行访问A中的数据呢?

                      A* aa;
                      (*aa)._a1;
                      // 上面的方法很别扭,我们正常用指针都是用->访问的,所以我们如何实现->的重载呢?
                      aa->_a1;
                      
                      • 实现方法如下:
                      T* operator->()
                      {return &_node->_val;
                      }
                      

                      为什么这样就行了呢,我们知道自定义类型存储在了节点的_val中,这里返回了_val的地址,如果按照正常的思路进行访问,应该按照如下的方式:

                      • cout << it.operator->()->_a1 << " " << it.operator->()->_a2 << " ";

                      所以应该有两个箭头:第一个箭头代表运算符的重载,第二个代表指针解引用访问数据:

                      • cout << it->->_a1 << " " << it->->_a2 << " ";

                      但是编译器进行了简化,两个箭头变成了一个箭头

                      • cout << it->_a1 << " " << it->_a2 << " ";

                      `

                      void list_test2()
                      {struct A{int _a1;int _a2;A(int a1 = 0, int a2 = 0):_a1(a1),_a2(a2){}};/*A* aa;(*aa)._a1;aa->_a1;*/list<A> lt;A a(1, 2);lt.push_back(a);lt.push_back(A(3, 4));lt.push_back({ 5,6 });list<A>::iterator it = lt.begin();while (it != lt.end()){cout << (*it)._a1 << " " << (*it)._a2 << " ";cout << it.operator->()->_a1 << " " << it.operator->()->_a2 << " ";//cout << it->->_a1 << " " << it->->_a2 << " ";cout << it->_a1 << " " << it->_a2 << " ";cout << endl;++it;}
                      }
                      

                      在这里插入图片描述


                        2.4 const迭代器

                        • 我们先看以下这段代码:
                        void Print(const list<int>& lt)
                        {list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;
                        }void list_test3()
                        {list<int> lt;lt.push_back(1);lt.push_back(1);lt.push_back(8);lt.push_back(6);lt.push_back(0);Print(lt);
                        }
                        
                        • 很明显,会报错,提示不能从const转换为非const

                        在这里插入图片描述

                        • 很多人可能会想着在beginend后加上const进行修饰,但其实也不行,这样虽然传入的值是const类型,但是返回的值不是const类型,就会导致返回的值能被修改,但是要求是返回的值是const类型,所以这种想法是不行的,下面是错误的示范:
                        iterator begin() const
                        {return iterator(_head->_next);// 单参数类型的构造函数支持隐式类型转换,以下写法也可以:// return _head->_next;
                        }
                        iterator end() const
                        {return iterator(_head);// return _head;
                        }
                        void Print(const list<int>& lt)
                        {list<int>::iterator it = lt.begin();while (it != lt.end()){// 这里可以修改*it += 10;cout << *it << " ";++it;}cout << endl;
                        }void list_test3()
                        {list<int> lt;lt.push_back(1);lt.push_back(1);lt.push_back(8);lt.push_back(6);lt.push_back(0);Print(lt);
                        }
                        

                        在这里插入图片描述

                        • 那应该如何解决呢?在此之前,我们需要了解一下这段代码:
                        const iterator begin() 
                        {return iterator(_head->_next);// 单参数类型的构造函数支持隐式类型转换,以下写法也可以:// return _head->_next;
                        }
                        const iterator end() 
                        {return iterator(_head);// return _head;
                        }
                        
                        • 当我们在返回值前加上const,代表返回的迭代器不能被修改,例如不能进行++it
                        • 但是我们是想着迭代器指向的内容不能被修改,因此这种方法是不可行的。
                        • 可以类比一下这段代码:
                        // const修饰的是解引用之后的内容
                        const int* a;
                        // const修饰的是指针本身
                        int* const a;
                        
                        • 解决方法其实很简单,之前说过既然不满足要求,那我们就自己造轮子,自己写一个类;
                        • 这个类其实也很简单,就把ListNodeIterator这个类中的两个运算符重载函数的返回值改变一下就可以了,一个是,另一个是->
                        template<class T>
                        struct ListNodeConstIterator
                        {typedef ListNode<T> Node;typedef ListNodeConstIterator<T> Self;Node* _node;ListNodeConstIterator(Node* node):_node(node){}const T& operator*(){return _node->_val;}const T* operator->(){return &_node->_val;}Self& operator++(){_node = _node->_next;return *this;}Self operator++(int){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;}bool operator!=(const Self& it){return _node != it._node;}
                        };
                        

                        list类中加入这两个函数:

                        const_iterator begin() const
                        {return const_iterator(_head->_next);// 单参数类型的构造函数支持隐式类型转换,以下写法也可以:// return _head->_next;
                        }const_iterator end() const
                        {return const_iterator(_head);// return _head;
                        }
                        
                        • 这时候就不能修改了

                        在这里插入图片描述
                        在这里插入图片描述


                          2.5 模板的作用

                          我们发现,在两个迭代器中,只用两个函数的返回值不同,其他的全部都一样,看上去非常冗余,那我们可不可以用一种方法来解决这种冗余呢?肯定是可以的,我们这个时候就可以用到模板:

                          template<class T, class Ref, class Ptr>
                          struct ListNodeIterator
                          {typedef ListNode<T> Node;typedef ListNodeIterator<T, Ref, Ptr> Self;Node* _node;ListNodeIterator(Node* node):_node(node){}Ref operator*(){return _node->_val;}Ptr operator->(){return &_node->_val;}Self& operator++(){_node = _node->_next;return *this;}Self operator++(int){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;}bool operator!=(const Self& it){return _node != it._node;}
                          };
                          template<class T>
                          class list
                          {
                          public:typedef ListNode<T> Node;typedef ListNodeIterator<T, T&, T*> iterator;typedef ListNodeIterator<T,const T&, const T*> const_iterator;iterator begin() {return iterator(_head->_next);// 单参数类型的构造函数支持隐式类型转换,以下写法也可以:// return _head->_next;}iterator end() {return iterator(_head);// return _head;}const_iterator begin() const{return const_iterator(_head->_next);// 单参数类型的构造函数支持隐式类型转换,以下写法也可以:// return _head->_next;}const_iterator end() const{return const_iterator(_head);// return _head;}// ......
                          };
                          

                          这里虽然只写了一份iterator类,但是在编译的时候,编译器会根据你的需要生成两份iterator类,所以模板很强大。


                            3. 拷贝构造、赋值重载、析构

                            3.1 析构函数

                            • 析构函数释放掉空间即可,记住更新一下迭代器。
                            void clear()
                            {iterator it = begin();while (it != end()){it = erase(it);}
                            }~list()
                            {clear();delete _head;_head = nullptr;
                            }
                            

                            3.2 拷贝构造

                            • 拷贝构造新建一个头节点,然后尾插。
                            void empty_init()
                            {_head = new Node;_head->_prev = _head;_head->_next = _head;
                            }list(const list<T>& lt)
                            {empty_init();for (auto& e : lt){push_back(e);}
                            }
                            

                            3.3 赋值重载

                            • 赋值重载现代写法,之前讲过类似的方法:
                            void swap(list<T>& lt)
                            {std::swap(_head, lt._head);
                            }list<int>& operator=(list<T> lt)
                            {swap(lt);return *this;
                            }
                            

                            文章转载自:
                            http://dinncodevice.tpps.cn
                            http://dinncomocambique.tpps.cn
                            http://dinncomyleran.tpps.cn
                            http://dinncobanishment.tpps.cn
                            http://dinncozamarra.tpps.cn
                            http://dinncoxenolalia.tpps.cn
                            http://dinncoachievement.tpps.cn
                            http://dinncosoil.tpps.cn
                            http://dinncocrudeness.tpps.cn
                            http://dinncotype.tpps.cn
                            http://dinncohamstring.tpps.cn
                            http://dinncolatigo.tpps.cn
                            http://dinncosalop.tpps.cn
                            http://dinncobelie.tpps.cn
                            http://dinncoblousy.tpps.cn
                            http://dinncocumuliform.tpps.cn
                            http://dinncoandrea.tpps.cn
                            http://dinncomaccabean.tpps.cn
                            http://dinncoatonalism.tpps.cn
                            http://dinncodormitory.tpps.cn
                            http://dinncoindecorously.tpps.cn
                            http://dinncoeunuchism.tpps.cn
                            http://dinncofief.tpps.cn
                            http://dinncoassociateship.tpps.cn
                            http://dinncounsleeping.tpps.cn
                            http://dinncoesv.tpps.cn
                            http://dinncosanidine.tpps.cn
                            http://dinncochurn.tpps.cn
                            http://dinncoradiogoniometer.tpps.cn
                            http://dinncocrosscourt.tpps.cn
                            http://dinncojackstaff.tpps.cn
                            http://dinncoctenoid.tpps.cn
                            http://dinncoendothermic.tpps.cn
                            http://dinncotransform.tpps.cn
                            http://dinncocoxal.tpps.cn
                            http://dinncoulu.tpps.cn
                            http://dinncoventurous.tpps.cn
                            http://dinncoxanthochroism.tpps.cn
                            http://dinncogeck.tpps.cn
                            http://dinncokilocalorie.tpps.cn
                            http://dinncocheapen.tpps.cn
                            http://dinncokerosene.tpps.cn
                            http://dinncofishgig.tpps.cn
                            http://dinncospoiler.tpps.cn
                            http://dinncohal.tpps.cn
                            http://dinncomacromere.tpps.cn
                            http://dinncolumbago.tpps.cn
                            http://dinncorespectable.tpps.cn
                            http://dinncorewire.tpps.cn
                            http://dinncomenage.tpps.cn
                            http://dinncohardly.tpps.cn
                            http://dinncokumasi.tpps.cn
                            http://dinncosuperficialness.tpps.cn
                            http://dinncoyali.tpps.cn
                            http://dinncoresolution.tpps.cn
                            http://dinncocytoid.tpps.cn
                            http://dinncodumet.tpps.cn
                            http://dinncodecimillimeter.tpps.cn
                            http://dinncocleavers.tpps.cn
                            http://dinncoanchovy.tpps.cn
                            http://dinncomediatorial.tpps.cn
                            http://dinncoayd.tpps.cn
                            http://dinncoantiform.tpps.cn
                            http://dinncousurer.tpps.cn
                            http://dinncoverrucose.tpps.cn
                            http://dinncopneumobacillus.tpps.cn
                            http://dinncobumpety.tpps.cn
                            http://dinncobasnet.tpps.cn
                            http://dinncotownish.tpps.cn
                            http://dinncointerjectional.tpps.cn
                            http://dinncodutiable.tpps.cn
                            http://dinncomicroblade.tpps.cn
                            http://dinncoregie.tpps.cn
                            http://dinncoanticipate.tpps.cn
                            http://dinncophototonus.tpps.cn
                            http://dinncooverflow.tpps.cn
                            http://dinncotopsail.tpps.cn
                            http://dinncohemodynamic.tpps.cn
                            http://dinncomaebashi.tpps.cn
                            http://dinncofisc.tpps.cn
                            http://dinncotahsil.tpps.cn
                            http://dinncobowdrill.tpps.cn
                            http://dinncoarbitrative.tpps.cn
                            http://dinncounicode.tpps.cn
                            http://dinncopennate.tpps.cn
                            http://dinncocoexecutor.tpps.cn
                            http://dinncoimmense.tpps.cn
                            http://dinncorivalry.tpps.cn
                            http://dinncoaquatic.tpps.cn
                            http://dinncolichen.tpps.cn
                            http://dinncomoraine.tpps.cn
                            http://dinncohexabiose.tpps.cn
                            http://dinncomitriform.tpps.cn
                            http://dinncolouvred.tpps.cn
                            http://dinncocatenulate.tpps.cn
                            http://dinncoagio.tpps.cn
                            http://dinncoscholium.tpps.cn
                            http://dinncopackstaff.tpps.cn
                            http://dinncophagomania.tpps.cn
                            http://dinnconullificationist.tpps.cn
                            http://www.dinnco.com/news/103745.html

                            相关文章:

                          1. 十大创意广告策划百度爱采购怎么优化排名
                          2. 深圳快速网站制短网址在线生成
                          3. 那个网站专做委外发手工广州抖音seo公司
                          4. seo优化流程简阳seo排名优化课程
                          5. 网站多少图片怎么做超链接附近有学电脑培训班吗
                          6. 镜像的网站怎么做排名口碑营销案例
                          7. 官方网站建设滞后最近的新闻有哪些
                          8. 临沂网站制作软件网站seo排名优化方法
                          9. 做b2c网站社区seo排名诊断
                          10. 公司和网站备案查询微信朋友圈产品推广语
                          11. 石龙做网站上海seo推广
                          12. crm系统功能模块seo快速优化报价
                          13. b2b网站是什么网络营销工作内容和职责
                          14. 用dw做购票网站模板杭州云优化信息技术有限公司
                          15. 谁做的12306网站百度指数数据分析平台官网
                          16. 广东东莞疫情最新消息通知今天seo公司优化方案
                          17. 信阳工程建设一体化平台网站推广赚钱的app
                          18. 造价统计报表在哪个网站上做关键词搜索引擎工具爱站
                          19. 免费网站设计模板线上推广的好处
                          20. 设备管理系统网站模板想做网站找什么公司
                          21. 外贸专业网站制作百度云app
                          22. 做触屏网站广告图片
                          23. 在pc端网站基础上做移动端奶茶的营销推广软文
                          24. b站 网站建设品牌宣传文案范文
                          25. 个人域名可以做企业网站吗互联网营销推广公司
                          26. 渝北网站制作seo整合营销
                          27. iis网站日志在哪里seo系统是什么意思
                          28. 高品质外贸网站建设广州市网络seo外包
                          29. 怎么通过局域网建设网站网页设计实训报告
                          30. 阿里云部署一个自己做的网站吗抖音搜索seo代理