赞
踩
list的底层是双向循环链表,可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代,与其他底层是顺序表的容器(vector,array,deque)相比,list在任意位置进行插入,移除元素更加高效;但是和这些底层是顺序表的容器相比,list最大的缺陷就是不支持任意位置的随机访问。
- public:
- Node* node;
list的成员变量只有一个节点类型的指针,它指向该双向循环链表的虚拟头节点。
- //无参构造函数
- list()
- {
- head = new Node();
- head->next = head;
- head->prev = head;
- }
- //利用模板函数以及迭代器来构造对象
- template<class Inputiterator>
- list(Inputiterator first, Inputiterator last)
- {
- head = new Node();
- head->next = head;
- head->prev = head;
- while (first != last)
- {
- push_back(*first);
- ++first;
- }
- }
- //深拷贝的拷贝构造函数,现代写法
- list(const list<T>& x)
- {
- head = new Node();
- head->next = head;
- head->prev = head;
- list<T> tmp(x.begin(), x.end());
- std::swap(head, tmp.head);
- }
- //取头节点的迭代器
- iterator begin()
- {
- return iterator(head->next);
- }
-
- const_iterator begin() const
- {
- return const_iterator(head->next);
- }
-
- //以最后一个元素的下一个位置的迭代器构造的_revese_iterator作为返回值,就是用正向迭代器模拟实现反向迭代器,这是一种复用的表现,可以减少代码量
- _revese_iterator rbegin()
- {
- return _revese_iterator(end());
- }
-
- const_reverse_iterator rbegin() const
- {
- return const_reverse_iterator(end());
- }
-
- //取尾节点(虚拟头节点)的迭代器
- iterator end()
- {
- return iterator(head);
- }
-
- const_iterator end() const
- {
- return const_iterator(head);
- }
-
- //以第一个元素的迭代器构造的_revese_iterator作为返回值,就是用正向迭代器模拟实现反向迭代器,这是一种复用的表现,可以减少代码量
- _revese_iterator rend()
- {
- return _revese_iterator(begin());
- }
-
- const_reverse_iterator rend() const
- {
- return const_reverse_iterator(begin());
- }
上面的_reverse_iterator反向迭代器是由正向迭代器构造实现的,这是一种设计模式,是一种复用的表现,可以减少代码量。
利用List对象里的节点构造出迭代器,然后就可以使用该迭代器来遍历List对象中的每一个节点,实现解引用迭代器对象来完成取节点中的值的操作,还可以通过++,--来实现List对象中节点的遍历,list类迭代器本质上也是一个类,一个可以完成List对象中节点遍历的类。
list的成员变量只有一个节点类型的指针,它指向该双向循环链表的虚拟头节点。
- public:
- Node* node;
- template<class T, class Ref, class Ptr>
- class __list_iterator
- {
- public:
- typedef ListNode<T> Node;
- typedef __list_iterator<T, Ref, Ptr> self;
- __list_iterator(Node* x)
- :node(x)
- {
- }
- //解引用运算符重载
- Ref operator*()
- {
- return node->data;
- }
- //-> 迭代器是借助节点的指针访问修改链表,这里表示用指针->->来获取数据,然后编译器会优化为指针->来获取数据
- Ptr operator->()
- {
- return &node->data;
- }
- //迭代器前置加加,返回加加后的迭代器
- self operator++()
- {
- node = node->next;
- return *this;
- }
- //迭代器后置加加,返回加加前的迭代器
- self operator++(int)
- {
- self tmp(node);
- node = node->next;
- return tmp;
- }
- //迭代器前置减减,返回减减后的迭代器
- self operator--()
- {
- node = node->prev;
- return *this;
- }
- //迭代器后置减减,返回减减前的迭代器
- self operator--(int)
- {
- self tmp(node);
- node = node->prev;
- return tmp;
- }
-
- //判断两个迭代器指向的内容是否相等
- bool operator!=(const self& it) const
- {
- if (it.node != node)
- {
- return true;
- }
- return false;
- }
-
- bool operator==(const self& it) const
- {
- return !(*this != it);
- }
-
- public:
- Node* node;
- };
它的作用是可以反向遍历List里面的每一个节点,它是由正向迭代器构造出来的,所以它所有功能都是由正向迭代器来实现的,与正向迭代器不同的是,当解引用反向迭代器的时候,取得不是当前迭代器指向的节点的值,而是取得是前一个节点的值,这是因为迭代器rend指向的是头节点,迭代器rbegin指向的是虚拟头节点。反向迭代器的--,和++操作,对应着正向迭代器的++,--操作。
- public:
- _iterator it;
是一个正向迭代器
- template<class iterator, class Ref, class Ptr>
- class resverse_iterator
- {
- public:
- typedef iterator _iterator;
- typedef resverse_iterator<iterator, Ref, Ptr> self;
- resverse_iterator(const _iterator& x)
- :it(x)
- {
- }
- //解引用运算符重载
- Ref operator*()
- {
- _iterator prev = it;
- return *(--prev);
- }
- //-> 迭代器是借助节点的指针访问修改链表,这里表示用指针->->来获取数据,然后编译器会优化为指针->来获取数据
- Ptr operator->()
- {
- _iterator prev = it;
- --prev;
- return &*(prev);
- }
- //迭代器前置加加,返回加加后的迭代器
- self operator++()
- {
- --it;
- return *this;
- }
- //迭代器后置加加,返回加加前的迭代器
- self operator++(int)
- {
- self tmp(it);
- --it;
- return tmp;
- }
- //迭代器前置减减,返回减减后的迭代器
- self operator--()
- {
- ++it;
- return *this;
- }
- //迭代器后置减减,返回减减前的迭代器
- self operator--(int)
- {
- self tmp(it);
- ++it;
- return tmp;
- }
-
- //判断两个迭代器指向的内容是否相等
- bool operator!=(const self& It) const
- {
- return it != It.it;
- }
-
- bool operator==(const self& It) const
- {
- return !(it != It.it);
- }
-
- public:
- _iterator it;
- };
在List链表中尾插一个节点
无返回值
(1)先在堆上申请一块空间,这块空间存放着一个新节点的值
(2)让虚拟头节点的prev指针指向新节点,尾节点的next指针指向新节点
(3)新节点的prev指向尾节点,新节点的next指向虚拟头节点
- //尾插一个元素
- void push_back(const T& val)
- {
- Node* newnode = new Node(val);
- Node* _prev = head->prev;
- _prev->next = newnode;
- newnode->prev = _prev;
- newnode->next = head;
- head->prev = newnode;
- }
删除List对象中某个迭代器指向的节点,它可以是复用实现尾删,头删,以及清空List对象全部有效节点等功能
返回下一个节点的迭代器
(1)要删除的节点的前一个节点指向要删除的节点的下一个节点
(2)释放要删除的节点的空间
- // 这里erase以后,pos是否失效?一定失效
- iterator erase(iterator pos)
- {
- assert(pos != end());
- Node* cur = pos.node;
- Node* pre = pos.node->prev;
- Node* _next = pos.node->next;
- pre->next = _next;
- _next->prev = pre;
- delete cur;
- iterator(_next);
- }
- //尾删一个元素
- void pop_back()
- {
- erase(--end());
- }
-
- //头删一个元素
- void pop_front()
- {
- erase(begin());
- }
-
- void clear()
- {
- //第一种方式:
- //list<int>::iterator it = begin();
- //while (it != end())
- //{
- // iterator del = it++;
- // delete del.node;
- //}
- //head->next = head;
- //head->prev = head;
- 另一种方式
- while (it != end())
- {
- erase(it++);
- }
- }
在迭代器pos指向的节点后面插入一个节点
返回插入的新节点的迭代器
(1)先在堆上申请一块空间,这块空间存放着一个新节点的值
(2)让迭代器pos指向的节点的prev指针指向新节点,迭代器pos指向的节点的前一个节点的next指针指向新节点
(3)新节点的prev指向迭代器pos指向的节点的前一个节点,新节点的next指向迭代器pos指向的节点
- // 这里insert以后,pos是否失效?一定失效
- iterator insert(iterator pos, const T& x)
- {
- Node* newnode = new Node(x);
- Node* _prev = pos.node->prev;
- _prev->next = newnode;
- newnode->prev = _prev;
- newnode->next = pos.node;
- pos.node->prev = newnode;
- return iterator(newnode);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。