List的实现

来源:互联网 发布:淘宝贷款额度可以作假 编辑:程序博客网 时间:2024/06/14 13:46

重要技术点:iterator可用于可用于任何需要使用const_iterator的例程里,反之则不是。
可以在表的末尾或前端添加一个额外的结点,这些额外的结点被称为哨兵结点,在头部的结点称为表头结点,在末端的结点称为尾结点。

版本1,未检测错误。

template <typename Object>class List{  private:    struct Node  //struct的成员默认为公有    {        Object data;        Node *prev;  //指向Node之前的指针        Node *next;  //指向Node之后的指针        Node(const Object& d=Object(), Node *p=NULL, Node *n=NULL):data(d), prev(p), next(n){}    };  //其中所有数据成员都是公有的。  public:    class const_iterator    {      public:        const_iterator():current(NULL)            {}        const Object& operator*() const          {return retrieve();}        const_iterator& operator++()        {            current = current->next;            return *this;        }  //给前缀形式指定空参数表以标识        const_iterator operator++(int)        {            const_iterator old = *this;            ++(*this);            return old;        }  //给后缀形式指定一个(匿名的)int参数以标识,int参数永远不使用。         bool operator==(const const_iterator& rhs) const           {return current == rhs.current;}         bool operator!=(const const_iterator& rhs) const           {return !(*this==rhs)}       protected:         Node *current;         Object& retrieve() const           {return current->data;}         const_iterator(Node *p):current(p)  //const_iterator的构造函数           {}         friend class List<Object>;  //友元声明,允许List类访问const_iterator的非公有成员    };    class iterator:public const_iterator    {      publiciterator()          {}        Object& operator*()          {return retrieve();}        const Object& operator*() const          {return const_iterator::operator*();}//在iterator中修改函数必须显式实现,否则原始的实现会被新加的修改函数隐藏。        iterator& operator++()        {          current = current->next;          return *this;        }        iterator operator++(int)        {          iterator old = *this;          ++(*this);          return old;        }      protected:        iterator(Node *p):const_iterator(p)          {}  //使用一个初始化表来初始化继承来的当前结点        friend class List<Object>;      };  public:    List()      {init();}  //零参数构造函数    List(const List& rhs)  //复制构造函数,这两个函数都要分配表头结点和尾结点,从而给出私有的init例程,init()生成一个空List。      {          init();          *this = rhs;      }    ~List()  //回收表头结点和尾结点,调用clear()时回收所有的其他结点。      {          clear();          delete head;          delete tail;      }    const List& operator=(const List& rhs)  //是通过调用公有方法实现的,而没有试图使用低级的指针操作。    {       if(this == &rhs)           return *this;       clear();       for(const_iterator itr = rhs.begin();itr != rhs.end(); ++itr)           push_back(*itr);       return *this;    }    iterator begin()      {return iterator(head->next);}    const_iterator begin() const      {return const_iterator(head->next);}    iterator end()      {return iterator(tail);}    const_iterator end() const      {return const_iterator(tail);}    int size() const      {return theSize;}    bool empty() const      {return size()==0;}    void clear()    {      while(!empty())         pop_front();    }    Object& front()      {return *begin();}//前面在迭代器的类定义中已经重载了*操作符,这里不能惯性地以为解引用之后还是指针。    const Object& front() const      {return *begin();}    Object& back()      {return *--end();}    const Object& back() const      {return *--end();}    void push_front(const Object& x)      {insert(begin(), x);}    void push_back(const Object& x)      {insert(end(), x);}    void pop_front()      {erase(begin());}    void pop_back()      {erase(--end());}    iterator insert(iterator itr, const Object& x)  //在itr之前插入x    {        Node *p = itr.current;        theSize++;        return iterator(p->prev = p->prev->next = new Node(x, p->prev, p));    }    //删除itr所指的结点    iterator erase(iterator itr)    {        Node *p = itr.current;        iterator retVal(p->next);        p->prev->next = p->next;        p->next->prev = p->prev;        delete p;        theSize--;        return retVal;    }    iterator erase(iterator start, iterator end)    {        for(iterator itr = start; itr != end;)            itr = erase(itr);        return end;    }  private:    int theSize;    Node *head;    Node *tail;    void init()    {        theSize = 0;        head = new Node;        tail = new Node;        head->next = tail;        tail->prev = head;    }};
0 0
原创粉丝点击