list
类似于是双向循环带头链表,适合在任何位置进行插入,删除,与vector不同的一点是,不能中括号向数组一样访问,list的插入不会申请额外的空间,所以不会发生迭代器失效,但是删除的时候回删除空间,有可能会引起迭代器的失效
1.list的构造函数
- 无参构造
- 拷贝构造
- 迭代器构造
- n个val构造
2.iterator的使用
- begin、rbegin
- end、rend
3.list的常用函数
- empty:检查是否为空
- size:返回个数
- ++、–、*、->的重载
- clear:清空容器
- insert插入、erase删除等
模拟实现
#pragma once
namespace ljc
{
template<class T>
class ListNode//结点类
{
public:
T m_val;
ListNode * m_prev;
ListNode * m_next;
ListNode(const T &val = T()) :
m_prev(nullptr),
m_next(nullptr),
m_val(val)
{
}
};
template<class T>
class list//list类:双向循环带头链表
{
ListNode<T> * m_head;
void createHead()
{
m_head = new ListNode<T>;
m_head->m_next = m_head->m_prev = m_head;
}
public:
class iterator
{
public:
ListNode<T> * m_pos;
iterator(ListNode<T> * val = nullptr) :
m_pos(val)
{
}
T & operator*()const
{
return m_pos->m_val;
}
T * operator->()const
{
return &m_pos->m_val;
}
iterator operator++()
{
m_pos = m_pos->m_next;
return *this;
}
iterator operator++(int)
{
iterator tmp = *this;
m_pos = m_pos->m_next;
return tmp;
}
iterator operator--()
{
m_pos = m_pos->m_prev;
return *this;
}
iterator operator--(int)
{
iterator tmp = *this;
m_pos = m_pos->m_prev;
return tmp;
}
bool operator==(const iterator & ci) const
{
return m_pos == ci.m_pos;
}
bool operator!=(const iterator & ci) const
{
return m_pos != ci.m_pos;
}
};
list()
{
createHead();
}
list(int n, const T &val = T())
{
createHead();
int i;
for (i = 0; i < n; i++)
{
push_back(val);
}
}
list(iterator start, iterator finish)
{
createHead();
insert(end(), start, finish);
}
list(T * start, T * finish)
{
createHead();
insert(end(), start, finish);
}
list(list<T> & l)
{
createHead();
insert(end(), l.begin(), l.end());
}
~list()
{
erase(begin(), end());
delete m_head;
}
void clear()
{
erase(begin(), end());
}
void push_back(const T &val)
{
insert(end(), val);
}
void push_front(const T &val)
{
insert(begin(), val);
}
void pop_front()
{
erase(begin());
}
int empty()
{
if (!m_head)
{
return 1;
}
return 0;
}
int size()
{
ListNode<T> * cur = m_head;
if (empty())
{
return 0;
}
int tmp = 0;
for (cur = m_head->m_next; cur != m_head; cur = cur->m_next)
{
tmp++;
}
return tmp;
}
iterator insert(iterator pos, const T &val)
{
ListNode<T> * cur = new ListNode<T>;
ListNode<T> * npos = pos.m_pos;
cur->m_val = val;
cur->m_prev = npos->m_prev;
cur->m_prev->m_next = cur;
cur->m_next = npos;
npos->m_prev = cur;
return cur;
}
iterator insert(iterator pos, T * start, T * finish)
{
T * tmp;
iterator tmpit = --pos;
pos++;
for (tmp = start; tmp != finish; tmp++)
{
insert(pos, *tmp);
}
return ++tmpit;
}
iterator insert(iterator pos, iterator start, iterator end)
{
iterator tmp;
iterator tmpit = --pos;
pos++;
for (tmp = start; tmp != end; tmp++)
{
insert(pos, *tmp);
}
return ++tmpit;
}
iterator erase(iterator pos)
{
ListNode<T> * npos = pos.m_pos;
ListNode<T> * res = npos->m_next;
npos->m_next->m_prev = npos->m_prev;
npos->m_prev->m_next = npos->m_next;
delete npos;
return res;
}
iterator erase(iterator start, iterator finish)
{
iterator i;
for (i = start; i != finish; i++)
{
erase(i);
}
return finish;
}
iterator begin()
{
return m_head->m_next;
}
iterator end()
{
return m_head;
}
};
};