目录
1.带头双向循环链表的迭代器实现
链表的基础框架(初始化和尾插)
- begin和end返回先要iterator构造函数初始化
#include<iostream>
using namespace std;
namespace lj
{
template<class T>
struct _list_node//struct全为公有
{
T _val;
_list_node<T>* _prev;
_list_node<T>* _next;
_list_node(const T x = T())
:_val(x)
,_prev(nullptr)
,_next(nullptr)
{}
};
template<class T>
class list
{
typedef _list_node<T> node;
public:
iterator begin()
{
return iterator(_head->_next);
}
const_iterator begin() const
{
return const_iterator(_head->_next);
}
iterator end()
{
return iterator(_head);
}
const_iterator end() const
{
return const_iterator(_head);
}
list()//构造函数
{
_head = new node;
_head -> _prev = _head;
_head -> _next = _head;
}
void push_back(const T& x)//尾插
{
node* newnode = new node(x);
node* tail = _head->_prev;
tail->_next = newnode;
newnode->_prev = tail;
newnode->_next = _head;
_head->_prev = newnode;
}
private:
node* _head;
};
2.迭代器
实现迭代器
- 为什么要自己实现迭代器
- 实现了可读可写的迭代器
template<class T>
struct _list_iterator
{
typedef _list_node<T> node;
typedef _list_iterator<T> self;
node* _pnode;
_list_iterator(node* pnode)//构造函数
:_pnode(pnode)
{}
T operator*()
{
return _pnode->_val;
}
bool operator!=(const self& s)const
{
return _pnode != s._pnode;
}
bool operator==(const self& s) const
{
return _pnode == s._pnode;
}
self& operator++()
{
_pnode = _pnode->_next;
return *this;
}
// it++ -> it.operator++(&it, 0)
self operator++(int)
{
self tmp(*this);
_pnode = _pnode->_next;
return tmp;
}
self& operator--()
{
_pnode = _pnode->_prev;
return *this;
}
self operator--(int)
{
self tmp(*this);
_pnode = _pnode->_prev;
return tmp;
}
};
void test_list()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
list<int>::iterator it = lt.begin();
while (it != lt.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
可读可写和可读的迭代器
- 把写的_list_node类,给const_iterator单独写一个类
- 那么代码出了operator*以外基本相同,要冗杂了
解决方法
- -list_iterator是一个类模板,可以实例化出两个例子;
template<class T, class Ref, class Ptr>
struct _list_iterator
{
typedef _list_node<T> node;
typedef _list_iterator<T, Ref, Ptr> self;
node* _pnode;
_list_iterator(node* pnode)//构造函数
:_pnode(pnode)
{}
Ref operator*()
{
return _pnode->_val;
}
bool operator!=(const self& s)const
{
return _pnode != s._pnode;
}
bool operator==(const self& s) const
{
return _pnode == s._pnode;
}
self operator++()
{
_pnode = _pnode->_next;
return *this;
}
// it++ -> it.operator++(&it, 0)
self operator++(int)
{
self tmp(*this);
_pnode = _pnode->_next;
return tmp;
}
self& operator--()
{
_pnode = _pnode->_prev;
return *this;
}
self operator--(int)
{
self tmp(*this);
_pnode = _pnode->_prev;
return tmp;
}
};
class list
{
typedef _list_node<T> node;
public:
typedef _list_iterator<T, T&, T*> iterator;//类模板会实例化两个例子
typedef _list_iterator<T, const T&, const T*> const_iterator;
};
3.list的一些特殊使用
使用数组初始化(通用)
- 原生指针可以当做天然的迭代器使用,其实vector/string的的迭代器也是原生指针
#include<iostream>
#include<list>
#include<vector>
using namespace std;
void test_list1()
{
int a[] = { 1,2,3,4 };
//原生指针可以当做天然的迭代器使用,其实vector/string的的迭代器也是原生指针
list<int>::iterator it = lt1.begin();//InputIterator first, InputIterator last
while (it != lt1.end())
{
cout << *it << " ";
it++;
}
cout << endl;
}
迭代器失效
- list因为底层结构insert不会导致pos迭代器失效
- list因为底层结构erase会导致pos迭代器失效,野指针
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
//list因为底层结构insert不会导致pos迭代器失效
lt.insert(pos, 30);
//list因为底层结构erase会导致pos迭代器失效,野指针
lt.erase(pos);