1. 程式人生 > >c++ list 類的模擬實現

c++ list 類的模擬實現

list的模擬實現
list的構成

list在底層是一條雙向迴圈連結串列,可以在常數時間內完成插入和刪除操作。最主要的缺點是無法隨機存取。而在連結串列可以將其中元素儲存在不相關的位置。

list的組成

list的本身和list的節點是不同的結構,list本身是由一個個的節點構成的。所以只需要完成對連結串列的操作即可。

list的節點類

與c中一樣,每一個節點都有資料域前後指標,通過一個類來構造每一個節點

 template<class T>   //節點類
  struct ListNode{

    typedef ListNode* point_type;
    point_type _prev;
    point_type _next;
    T _data;

    ListNode(const T& value = T())
      :_prev(nullptr),
      _next(nullptr),
      _data(value)
    {}

    };
list的迭代器類

list中的迭代器並不與之前的vetcor一樣是原生指標,而是需要我們進行封裝,主要是對於運算子進行過載已達到目的

正向迭代器
  template<class T,class Ref,class Ptr>
  struct List_iterator{
    typedef ListNode<T> Node;
    typedef List_iterator<T,Ref,Ptr> self;
    typedef T value_type;
    Node* _node;  //指向list中的每個節點的指標


    //迭代器的構造
    List_iterator(Node* node)
      :_node(node)
    {}

    T& operator*()
    {
      return _node->_data;
    }

    T* operator->()
    {
      return &(operator*());
    }


    //迭代器的比較
    bool operator==(const self& node)
    {
      return _node == node._node;
    }

    bool operator!=(const self& node)
    {
      return _node != node._node;
    }

    //迭代器的++
    //對於操作運算子++,--的過載,編譯器底層認為有兩個引數的為後置++,一個引數的為前置++
    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;
    }

};
反向迭代器

反向迭代器,主要是要傳入一個正向的迭代器,對正向的迭代器進行再次的封裝

  template<class T,class Ref,class Ptr,class Iterator>
  struct List_reverse_iterator{
    typedef ListNode<T> Node;
    typedef List_reverse_iterator<T,Ref,Ptr,Iterator> self;
    typedef T value_type;
    Iterator _it;  //傳入的一個正向迭代器


    //反向迭代器的構造
    List_reverse_iterator(const Iterator& it)
      :_it(it)
    {}

    Ref operator*()
    {
      return *_it;  //已經過載過正向迭代器的*所以直接使用即可
    }

    Ptr operator->()
    {
      return &(operator*());
    }


    //反向迭代器的比較
    bool operator==(const self& node)
    {
      return _it == node._it;
    }

    bool operator!=(const self& node)
    {
      return _it != node._it;
    }

    //反向迭代器的++
    self operator++()     //前置++
    {
      --_it;  //相當與正向迭代器的++
      return *this;
    }

    self operator++(int)  //後置++
    {
      self tmp = *this;
      _it--;
      return tmp;
    }

    //迭代器--
    self& operator--()   //前置--
    {
      ++_it;
      return *this;
    }

    self operator--(int)  //後置--
    {
      self tmp = *this;
      _it++;
      return tmp;
    }
};
list的構造及容量,插入刪除
  template<class T>  //list類
  class List{
    typedef ListNode<T> Node;
    public:
    typedef T value_type;
    typedef List_iterator<T, T& ,T*> iterator;
    typedef List_iterator< T, const T& ,const T*> const_iterator;
    typedef List_reverse_iterator<T, T& ,T*,iterator> reverse_iterator; 
      //迭代器函式
      iterator begin()
      {
        return iterator(_hnode->_next);
      }

      iterator end()
      {
        return iterator(_hnode);
      }

      const_iterator cbegin() const 
      {
        return const_iterator(_hnode->_next);
      }

      const_iterator cend() const
      {
        return const_iterator(_hnode);
      }

      //反選迭代器
      reverse_iterator rbegin()
      {
        return reverse_iterator(iterator(_hnode->_prev));
      }

      reverse_iterator rend()
      {
        return reverse_iterator(iterator(_hnode));
      }

      //建構函式
      List()  //無參構造
      :_hnode(new Node)
      {
        _hnode->_next = _hnode;
        _hnode->_prev = _hnode;
      }

    //帶參構造
      List(int size, const value_type& value = value_type() )
        :_hnode(new Node)
      {
        _hnode->_next = _hnode;
        _hnode->_prev = _hnode;
        while(size--)
        {
          Push_back(value);  //將所給初始化值進行尾插
        }
      }

    //拷貝構造
      List( List<value_type>& l)
        :_hnode(new Node)
      {

        _hnode->_next = _hnode;
        _hnode->_prev = _hnode;
        const_iterator it2 = l.cbegin();
        while(it2 != l.cend())
        {
          Push_back(*it2);
          it2++;
        }
                   
      }

    //使用迭代器區間對構造進行初始化
      template<class InputIterator>
      List(InputIterator first, InputIterator last)
      {

       _hnode = new Node;
        _hnode->_next = _hnode;
        _hnode->_prev = _hnode;
        while(first != last)
        {
          Push_back(*first);
          first++;
        }
      }

    //賦值運算子的過載
      List<value_type>& operator=( List<value_type>& list)
      {

        List<value_type> tmp(list); //拷貝一臨時物件,與原物件交換頭節點指標
        swap(_hnode,list._hnode);

        return *this;
      }

      ~List()
      {
        Clear();
       delete _hnode;
        _hnode = NULL;
      }
      
      //容量
      bool Empty()
      {
        return _hnode->_next == _hnode ;
      }

      int Size()
      {
        int count = 0;
        iterator it = begin();
        while(it != end())
        {
          count++;
          it++;
        }

        return count;
      }

      iterator Insert(iterator pos, const value_type value)
      {
        Node* newnode = new Node(value);

        newnode->_next = pos._node;
        newnode->_prev = pos._node->_prev;
        pos._node->_prev->_next = newnode;
        pos._node->_prev = newnode;

        return iterator(newnode);  //返回插入位置的迭代器   
      }

 
      void Push_back(const value_type& value) //尾插
      {
        Insert(end(),value);
      }
  
      void Push_front(const value_type& value)   //頭插
      {
        Insert(begin(),value);
      }

      void DestoryNode(Node* pl)
      {
        delete pl;
      }
      
      iterator Erase(iterator pos)
      {   //移除一個節點
        Node* next = pos._node->_next;
        Node* prev = pos._node->_prev;
        Node* cur = pos._node;
        iterator tmp = cur->_next;

        next->_prev = prev;
        prev->_next = next;

        DestoryNode(cur);

        return iterator(tmp);  //返回被刪除節點的下一個位置的節點
        
      }

      void Pop_back()
      {
          Erase(--end());
      }

      void Pop_front()
      {
          Erase(begin());
      }      


      void Clear();
      void Remove(const value_type& value);
      void Unique();

    private:
       //一個指向連結串列頭節點的指標
       Node* _hnode;

  };
}

#endif
對list的操作
    //清除連結串列,只保留頭節點
      template<class value_type>
      void mylist::List<value_type>::Clear()
      {   
        while(_hnode->_next != _hnode)
        {
          Pop_back();
        }

      }

    //刪除所有指定元素
      template<class value_type>
      void mylist::List<value_type>::Remove(const value_type& value)
      {
        iterator it = begin();
        while(it != end())
        {
          if(*it == value)
          {
            it = Rrase(it);
          }
          else it++;
        }
      }

    //刪除元素,使相鄰元素不重複
     template<class value_type>
     void mylist::List<value_type>::Unique()
     {
       iterator it = begin();
       iterator last = --end();
       while(it != last)
       {
         if(*it == *(++it))
         {
           it = Erase(--it);
         }
         
       }
    }