模拟实现简化版List迭代器&嵌入List

时间:2023-03-08 20:41:48
模拟实现简化版List迭代器&嵌入List

1、迭代器(iterators)概念
(1)迭代器是一种抽象的设计概念,其定义为:提供一种方法,使他能够按顺序遍历某个聚合体(容器)所包含的所有元素,但又不需要暴露该容器的内部表现方式。

(2)迭代器是一种行为类似智能指针的对象, 而指针最常见的行为就是内 容提领和成员 访问。 因此迭代器最重要的行为就是对operator*和operator->进行重载。

(3)STL的中心思想在于: 将数据容器和算法分开, 彼此独立设计, 最后再以一贴胶合剂( iterator) 将它们撮合在一起。STL的迭代器是一个可遍历STL容器全部或者部分数据。

2、迭代器的使用

以list和vector为例说明

 #include<iostream>
#include<vector>
#include<list>
#include<algorithm>
#include<string>
using namespace std;
void Test1()
{
vector<int>v1;
v1. push_back() ;
v1. push_back() ;
v1. push_back() ;
v1. push_back() ;
v1. push_back() ;
//迭代器遍历顺序表
vector<int>: : iteratorit=v1. begin() ;
for(; it! =v1. end() ; ++it)
{
cout<<*it<<" ";
}
cout<<endl;
// STL的排序算法
sort(v1. begin() , v1. end() ) ;
it=v1. begin() ;
for(; it! =v1. end() ; ++it)
{
cout<<*it<<" ";
}
cout<<endl;
}
voidTest2()
{
list<string>l1;
l1. push_back("xjh") ;
l1. push_back("zpw") ;
l1. push_back("yb") ;
l1. push_back("whb") ;
//迭代器遍历链表
list<string>: : iteratorit=l1. begin() ;
for(; it! =l1. end() ; ++it)
{
cout<<*it<<" ";
}
cout<<endl;
// STL的替换算法
replace(l1. begin() , l1. end() , "xjh", "lcf") ;
it=l1. begin() ;
for(; it! =l1. end() ; ++it)
{
cout<<*it<<" ";
}
cout<<endl;
}
voidTest3()
{
list<string>l1;
l1. push_back("xjh") ;
l1. push_back("zpw") ;
l1. push_back("yb") ;
l1. push_back("whb") ;
//迭代器遍历链表
list<string>: : iteratorit=l1. begin() ;
for(; it! =l1. end() ; ++it)
{
cout<<*it<<" ";
}
cout<<endl;
// STL的find算法查找迭代器区间的数据, 并返回找到节点的迭代器
it=find(l1. begin() , l1. end() , "yb") ;
if(it! =l1. end() )
{
cout<<"find success: "<<*it<<endl;
//通过迭代器修改节点数据
*it="yls";
}
it=find(l1. begin() , l1. end() , "yb") ;
if(it==l1. end() )
{
cout<<"find failed"<<endl;
}
}

3、什么是迭代器失效
以vector为例,当我们插入一个元素时它的预分配空间不够时,它会重新申请一段新空间,将原空间上的元素 复制到新的空间上去,然后再把新加入的元素放到新空间的尾部,以满足vector元素要求连续存储的目的。而后原空间会被系统撤销或征做他用,于是指向原 空间的迭代器就成了类似于“悬垂指针”一样的东西,指向了一片非法区域。如果使用了这样的迭代器会导致严重的运行时错误就变得很自然了。这也是许多书上叙 述vector在insert操作后“可能导致所有迭代器实效”的原因。但是想到这里我不禁想到vector的erase操作的叙述是“会导致指向删除元 素和删除元素之后的迭代器失效”。

 void PrintVector(vector<int>&v)
{
vector<int>: : iteratorit=v. begin() ;
for(; it! =v. end() ; ++it)
{
cout<<*it<<" ";
}
cout<<endl;
}
void Test1()
{
vector<int>v1;
v1. push_back() ;
v1. push_back() ;
v1. push_back() ;
v1. push_back() ;
v1. push_back() ;
v1. push_back() ;
v1. push_back() ;
v1. push_back() ;
PrintVector(v1) ;
//迭代器失效
vector<int>: : iteratorit=v1. begin() ;
while(it! =v1. end() )
{
if(*it% == )
it=v1. erase(it) ;
else
++it;
}
PrintVector(v1) ;
}
void PrintList(list<int>&l1)
{
list<int>: : iteratorit=l1. begin() ;
for(; it! =l1. end() ; ++it)
{
cout<<*it<<" ";
}
cout<<endl;
}
void Test2()
{
list<int>l1;
l1. push_back() ;
l1. push_back() ;
l1. push_back() ;
l1. push_back() ;
l1. push_back() ;
l1. push_back() ;
l1. push_back() ;
l1. push_back() ;
PrintList(l1) ;
//迭代器失效
list<int>: : iteratorit=l1. begin() ;
while(it! =l1. end() )
{
if(*it% == )
it=l1. erase(it) ;
else
++it;
}
PrintList(l1) ;
}
 // 1.正向迭代器/反向迭代器
// 2.const/非const
void PrintList(const list<int>& l)
{
list<int>::const_iterator it = l.begin();
while (it != l.end())
{
cout<<*it<<" ";
++it;
}
cout<<endl; list<int>::const_reverse_iterator rit = l.rbegin();
while (rit != l.rend())
{
//*rit = 10;
cout<<*rit<<" ";
++rit;
}
cout<<endl; //list<int>::iterator it1 = l.end();
//while (it1 != l.begin())
//{
// --it1;
// cout<<*it1<<" ";
//}
//cout<<endl;
}

归纳一下迭代器失效的类型:

(1)由于容器元素整体“迁移”导致存放原容器元素的空间不再有效,从而使得指向原空间的迭代器失效。

(2)由于删除元素使得某些元素次序发生变化使得原本指向某元素的迭代器不再指向希望指向的元素。

4、模拟实现简化版List迭代器&嵌入List

 #pragma once
#include<iostream>
#include<assert.h>
using namespace std; template <class T>
struct ItListNode
{
ItListNode<T>* _prev; // 指向前一个结点的指针
ItListNode<T>* _next; // 指向后一个结点的指针
T data; // 结点数据
ItListNode(const T& n)
:_prev(NULL)
,_next(NULL)
,data(n)
{}
};
// List的迭代器
template <class T, class Ref, class Ptr>
class ListIterator
{
public:
typedef ItListNode<T> Node;
Node* node; // 指向节点的指针
// 这里Ref、 Ptr模板参数主要是为了方便复用的方式实现const类型的迭代器ConstIterator
typedef ListIterator<T, Ref, Ptr> Self; ListIterator(Node* n)
:node(n)
{}
Ref operator*() {
return node->data;
}
Ptr operator->() {
return &node->data;
//return &(operator*());
}
Self& operator--() {
node = node->_prev;
return *this;
}
Self& operator--(int) {
Self tmp(*this);
node = node->_prev;
return tmp;
}
Self& operator++() {
node = node->_next;
return *this;
}
Self& operator++(int) {
Self tmp(*this);
node = node->_next;
return tmp;
}
bool operator != (const Self& s)const {
return node != s.node;
}
}; //双向循环链表
template <class T>
class List
{
typedef ItListNode<T> Node;
public: // 定义迭代器、 const迭代器
typedef ListIterator<T, T&, T*> Iterator;
typedef ListIterator<T, const T&, const T*> ConIterator;
List() {
Head = BuyNode(T());
Head->_prev = Head;
Head->_next = Head;
}
List(const T& l)
:Head(BuyNode(T()))
{
Head->_next = Head;
Head->_prev = Head;
ConIterator it = l.Begin();
while (it != l.End()) {
this->PushBack(*it);
++it;
}
}
List<T>& operator=(const T& l) {
if (*this != &l) {
swap(node, l.node);
}
return *this;
}
~List() {
Clear();
delete Head;
Head = NULL;
}
Iterator Begin() {
return Iterator(Head->_next);
}
ConIterator Begin()const {
return ConIterator(Head->_next);
}
Iterator End() {
return Iterator(Head);
}
ConIterator End()const {
return ConIterator(Head);
}
void Clear() {
Node*cur = Head->_next;
while (cur != Head) {
Node* next = cur->_next;
delete cur;
cur = next;
}
Head->_next = Head;
Head->_prev = Head;
}
void PushBack(const T& n) {
/*Node* tail = Head->_prev;
Node* tmp = BuyNode(n);
tail->_next = tmp;
tmp->_prev = tail;
tmp->_next = Head;
Head->_prev = tmp;*/
Insert(End(), n);
}
void PopBack() {
Erase(--End());
}
void PushFront(const T& n) {
Insert(Begin(), n);
}
void PopFront() {
Erase(Begin());
}
// 在pos前插入一个节点
void Insert(Iterator pos, const T& n) {
Node* Next = pos.node;
Node* Prev = Next->_prev;
Node* Cur = BuyNode(n);
Prev->_next = Cur;
Cur->_prev = Prev;
Cur->_next = Next;
Next->_prev = Cur;
}
// 在pos前插入一个节点
Iterator Erase(Iterator pos) {
assert(pos.node&&pos.node != Head);
Node* Cur = pos.node;
Node* Prev = Cur -> _prev;
Node* Next = Cur -> _next;
delete Cur;
Prev->_next = Next;
Next->_prev = Prev;
return Iterator(Next);
}
Iterator Find(const T& n) {
Iteraptor* it = Begin();
while (it != End()) {
if (*it == n)
return it;
}
return End();
} protected:
Node* BuyNode(const T& n) {
return new Node(n);
} private:
Node* Head;
}; // 1.测试List迭代器Iterator
void PrintList1(List<int>& l1)
{
List<int>::Iterator it = l1.Begin();
for (; it != l1.End(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
//2.测试List迭代器ConstIterator
void PrintMyList(const List<int>& L1) {
List<int>::ConIterator it1 = L1.Begin();
while (it1 != L1.End()) {
cout << *it1 << " ";
++it1;
}
cout << endl;
}
int main() {
List<int> L1;
L1.PushBack();
L1.PushBack();
L1.PushBack();
L1.PushBack();
PrintMyList(L1); PrintList1(L1);
L1.PopBack();
PrintMyList(L1); L1.PushFront();
L1.PushFront();
L1.PushFront();
L1.PushFront();
PrintMyList(L1);
L1.PopFront();
PrintMyList(L1); getchar();
return ;
}