list的底层实现
list的介绍list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向 其前一个元素和后一个元素。list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高 效。 比特科技构造函数 接口说明l...
·
list的介绍
- list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
- list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向 其前一个元素和后一个元素。
- list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高 效。 比特科技
构造函数 接口说明
list() 构造空的list
list (size_type n, const value_type& val = value_type()) 构造的list中包含n个值为val的元素
list (const list& x) 拷贝构造函数
list (InputIterator first, InputIterator last) 用[first, last)区间中的元素构造list - 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率 更好。
- 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list 的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间 开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这 可能是一个重要的因素)
list的迭代器
迭代器有两种实现方式:
一. 原生态指针,比如:vector
二. 将原生态指针进行封装,因迭代器的使用形式与指针完全相同,因此,在自定义的类中必须实 现以下方 法:
- 指针可以解引用,迭代器的类中必须重载operator*()
- 指针可以通过->访问其所指空间成员,迭代器类中必须重载oprator->()
- 指针可以++向后移动,迭代器类中必须重载operator++()与operator++(int)至于
operator–()/operator–(int)释放需要重载,根据具体的结构来抉择,双向链表可以向前 移 动,所以需要重载,如果是forward_list就不需要重载 - 迭代器需要进行是否相等的比较,因此还需要重载operator==()与operator!=()
代码:list的实现全部在代码中,代码中有注释
#include <iostream>
using namespace std;
template <class T>
struct ListNode
{
ListNode(const T& val = T())
:_next(nullptr)
, _prev(nullptr)
, _data(val)
{}
ListNode<T>* _next;
ListNode<T>* _prev;
T _data;
};
template <class T, class Ref, class Ptr>
struct ListIterator
{
typedef ListNode<T>* pNode;
typedef ListIterator<T, Ref, Ptr> self;
pNode _node;
ListIterator(pNode node)
:_node(node)
{}
// ++iterator
self& operator++()
{
_node = _node->_next;
return *this;
}
//iterator++
//移动到下一个节点的位置
self operator++(int)
{
self tmp(*this);
_node = _node->_next;
return tmp;
}
self& operator--()
{
_node = _node->_prev;
return *this;
}
// it--, 返回没有变之前的值,然后自身--
self operator--(int)
{
self tmp(*this);
_node = _node->_prev;
return tmp;
}
//*iterator
//获取节点的data
Ref operator*()
{
return _node->_data;
}
// struct a{int b, int c, int d} a *pa, pa->b,
// iterator->->
Ptr operator->()
{
return &_node->_data;
}
// iterator != l.end()
//比较两个迭代器封装的节点是否一样
bool operator!=(const self& it)
{
return _node != it._node;
}
};
template <class T>
class List
{
public:
typedef ListNode<T> Node;
typedef Node* pNode;
typedef ListIterator<T, T&, T*> iterator;
//const对象不能调用非const成员函数,只能调用const成员函数,
//但是const成员函数operator++, operator--,就不能修改成员_node的值,
//导致const迭代器无法执行++,--操作,故如下定义const迭代器不行
/pedef const ListIterator<T> const_iterator;
// *it ->
typedef ListIterator<T, const T&, const T*> const_iterator;
List(const T& val = T())
:_head(new Node(val))
{
_head->_next = _head;
_head->_prev = _head;
}
List(const List<T>& lst)
{
//首先创建头指针
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
//拷贝每一个节点,迭代器从头开始遍历每一个节点
//插入到当前list对象中去
for (const auto& e : lst)
{
PushBack(e);
}
}
//传统写法
//List<T>& operator=(const List<T>& lst)
//{
// if (this != &lst)
// {
// //释放原有节点
// Clear();
// for (const auto& e : lst)
// {
// PushBack(e);
// }
// }
// return *this;
//}
//现代写法
list<T>& operator=(List<T> lst)
{
swap(_head, lst._head);
return *this;
}
void PushBack(const T& val)
{
/*pNode curNode = new Node(val);
pNode prev = _head->_prev;
prev->_next = curNode;
curNode->_prev = prev;
curNode->_next = _head;
_head->_prev = curNode;*/
Insert(end(), val);
}
void PushFront(const T& val)
{
Insert(begin(), val);
}
iterator begin()
{
return iterator(_head->_next);
}
iterator end()
{
return iterator(_head);
}
const_iterator begin() const
{
return const_iterator(_head->_next);
}
const_iterator end() const
{
return const_iterator(_head);
}
void Insert(iterator pos, const T& val)
{
pNode newnode = new Node(val);
pNode cur = pos._node;
pNode prev = cur->_prev;
prev->_next = newnode;
newnode->_prev = prev;
newnode->_next = cur;
cur->_prev = newnode;
}
void PopFront()
{
Erase(begin());
}
void PopBack()
{
Erase(--end());
}
void Clear()
{
if (_head)
{
pNode cur = _head->_next;
while (cur != _head)
{
pNode next = cur->_next;
delete cur;
cur = next;
}
_head->_next = _head;
_head->_prev = _head;
}
}
//Erase: 迭代器失效
//获取Erase的返回值(当前被删除的节点的下一个位置),更新迭代器
iterator Erase(iterator pos)
{
if (pos != end())
{
pNode cur = pos._node;
pNode prev = cur->_prev;
pNode next = cur->_next;
prev->_next = next;
next->_prev = prev;
delete cur;
//更新迭代器,指向下一个位置
pos = iterator(next);
}
return pos;
}
~List()
{
Clear();
if (_head)
{
delete _head;
_head = nullptr;
}
}
private:
pNode _head;
};
更多推荐
已为社区贡献1条内容
所有评论(0)