【C++】C++ STL 探索:List使用与背后底层逻辑(三)

简介: 【C++】C++ STL 探索:List使用与背后底层逻辑

【C++】C++ STL 探索:List使用与背后底层逻辑(二)https://developer.aliyun.com/article/1617349


List.h

#include <iostream>
using namespace std;
//链表 任意位置插入 不怕迭代器失效
//链表 任意位置删除 怕迭代器失效 对此需要传下一个位置的迭代器
namespace bit
{
  //节点
  template<class T>
  struct ListNode
  {
    ListNode<T>* _next;
    ListNode<T>* _prev;
    T _data;
    //创建节点,是传数据创建的
    ListNode(const T& x = T())
      :_next(nullptr)
      ,_prev(nullptr)
      ,_data(x)
    {}
  };
  //template<class T>
  //
  template<class T,class Ref, class Ptr>
  struct ListIterator
  {
    typedef ListNode<T> Node;
    typedef  ListIterator<T,Ref,Ptr> Self;
    Node* _node;
    
    //迭代器还是依赖指针,通过类来改变运算符的行为
    //这里是浅拷贝 拷贝构造函数
    ListIterator(Node* node)
      :_node(node)
    {}
    //Self& operator++()
    Self& operator++()
    {
      _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)
    {
      //构造一个tmp临时变量
      Self tmp(*this);
      _node = _node->_prev;
      return tmp;
    }
    // T& operator* ()
      Ref operator* ()
    {
      return _node->_data;
    }
     //通过指针指向的节点去判断是否相等
     bool operator==(const Self& it)
     {
       return _node == it._node;
    }
     bool operator!=(const Self& it)
     {
       return _node != it._node;
     }
     //T* operator->()
    Ptr operator->()
     {
       return &_head->_data;
     }
  };
  //template<class T>
  //struct ListConIterator
  //{
  //  typedef ListNode<T> Node;
  //  typedef  ListConIterator<T> Self;
  //  //只针对解引用 修改了迭代器的行为 但是++ --是将迭代器位置改变,迭代器指向的内容不能被修改
  //  Node* _node;
  //  //迭代器还是依赖指针,通过类来改变运算符的行为
  //  //这里是浅拷贝 拷贝构造函数
  //  ListIterator(Node* node)
  //    :_node(node)
  //  {}
  //  Self& operator++()
  //  {
  //    _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) 
  //  {
  //    //构造一个tmp临时变量
  //    Self tmp(*this);
  //    _node = _node->_prev;
  //    return tmp;
  //  }
  //   
  //   T& operator* () 
  //  {
  //    return _node->_data;
  //  }
  //  //通过指针指向的节点去判断是否相等
  //  bool operator==(const Self& it)
  //  {
  //    return _node == it._node;
  //  }
  //  bool operator!=(const Self& it)
  //  {
  //    return _node != it._node;
  //  }
  //   T* operator->() 
  //  {
  //    return &_head->_data;
  //  }
  //};
  template<class T>
  class list
  {
    typedef ListNode<T> Node;
    public:
      //typedef  ListIterator<T> Iterator;
      typedef ListIterator<T, T&, T*> Iterator;
      typedef ListIterator<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 _head->_next;
      }
      const Iterator end() const
      {
        return _head;
      }
      const_Iterator begin() const
      {
        //return Iterator(_head->_next);
        //单参数的拷贝构造函数支持隐式类型转换
        return _head->_next;
      }
      const_Iterator end() const
      {
        //return Iterator(_head);
        return _head;
      }
      //构造-->同时拷贝需要也需要一份节点 那么就可以复用同一份
      void empty_init()
      {
        _head = new Node;
        _head->_next = _head;
        _head->_prev = _head;
        //不需要 newndoe->date 在实例化时,data已经是0了
        _size = 0;
      }
      
      list()
      {
        empty_init();
      }
      
      //拷贝构造
       list(const list<T>& lt)
      {
        empty_init();
        for (auto e : lt)
        {
          push_back(e);
        }
      }
      
       list<T>& operator=(list<T>& it)
       {
         swap(it);       
         return *this;
       }
       void swap(list<T>& it)
       {
         std::swap(_head, it._head);
         std::swap(_size, it._size);
       }
       //通过迭代器来实现
      void  insert(Iterator pos, const T& val)
       {
         Node* newnode = new Node(val);
         Node* cur = pos._node;
         Node* prev = cur->_prev;
         
         newnode->_next = cur;
         newnode-> _prev = prev;
         cur->_prev = newnode;
         prev->_next = newnode;
         _size++;
       }
      //这些需要使用迭代器作为返回类型,怕出现迭代器失效
      Iterator& erase(Iterator pos)
       {
        Node* cur = pos._node;
        Node* next = cur->_next;
        Node* prev = cur->_prev;
        delete cur;
        next->_prev = prev;
        prev->_next = next;
        
        _size--;
        //注意点
        return Iterator(next);
       }
      
      void push_back(const T& val)
      {
        insert(end(), val);
      }
      void pop_back()
      {
        erase(--end());
      }
      void push_front(const T& val)
      {
        insert(begin(), val);
      }
      void pop_front()
      {
        erase(begin());
      }
      void clear()
      {
        Iterator it = begin();
        while (it != end())
        {
          it = erase(it);
        }
      }
      ~list()
      {
        clear();        
        delete _head;
        _head = nullptr;
      }
       //获得基本信息
       size_t size()
       {
         return _size;
       }
       bool empty()
       {
         return _size == 0;
       }
    private:
      //创建哨兵位
      Node* _head;
      size_t _size;
  };
  struct A
  {
    int a1 = 0, a2 = 0;
    
    A(int a1 , int a2)
      :a1(1)
      ,a2(2)
    {}
  };
  void PrintList(const list<int>& clt)
  {
    list<int> ::Iterator it = clt.begin();
    while (it != clt.end())
    {
      *it += 10;
      cout << *it << " ";
      ++it;
    }
    cout << endl;
  }
  void list_test()
  {
    //list<int> it;
    先插入
    //it.push_back(1);
    //it.push_back(2);
    //list<int> :: Iterator lt = it.begin();
    
    //A* ptr = &a1
    // (*ptr).a1;
    // ptr->_a1
    //返回的是临时变量 是一份临时拷贝 具有常性
    list<A> lt;
    list<A> ::Iterator it = lt.begin();
    lt.push_back(A(1,2));
    lt.push_back({3,3});
    while (it != lt.end())
    {
      cout << *it;
      it++;
    }
  }
}


以上就是本篇文章的所有内容,在此感谢大家的观看!这里是店小二呀C++笔记,希望对你在学习C++语言旅途中有所帮助!

相关文章
|
1月前
|
存储 程序员 C++
C++常用基础知识—STL库(2)
C++常用基础知识—STL库(2)
68 5
|
30天前
|
存储 算法 C++
【C++打怪之路Lv10】-- list
【C++打怪之路Lv10】-- list
20 1
|
1月前
|
存储 自然语言处理 程序员
C++常用基础知识—STL库(1)
C++常用基础知识—STL库(1)
52 1
|
1月前
|
算法 安全 Linux
【C++STL简介】——我与C++的不解之缘(八)
【C++STL简介】——我与C++的不解之缘(八)
|
1月前
|
算法 数据处理 C++
c++ STL划分算法;partition()、partition_copy()、stable_partition()、partition_point()详解
这些算法是C++ STL中处理和组织数据的强大工具,能够高效地实现复杂的数据处理逻辑。理解它们的差异和应用场景,将有助于编写更加高效和清晰的C++代码。
22 0
|
1月前
|
存储 缓存 C++
C++番外篇——list与vector的比较
C++番外篇——list与vector的比较
21 0
|
1月前
|
C++
C++番外篇——list的实现
C++番外篇——list的实现
19 0
|
1月前
|
存储 C++ 容器
C++入门9——list的使用
C++入门9——list的使用
18 0
|
5月前
|
安全 Java
java线程之List集合并发安全问题及解决方案
java线程之List集合并发安全问题及解决方案
890 1
|
4月前
|
Java API Apache
怎么在在 Java 中对List进行分区
本文介绍了如何将列表拆分为给定大小的子列表。尽管标准Java集合API未直接支持此功能,但Guava和Apache Commons Collections提供了相关API。