mylist.h
#pragma once
#include"ReverseIterator.h"
template<class T>
struct listnode //链表的节点
{
T _data;
listnode<T> *_next;
listnode<T> *_prev;
listnode(const T& data)
:_data(data), _next(0), _prev(0)
{}
};
//假如没有迭代器,而你又没有提供print函数(即使提供也不一定能满足用户的打印需求)
// 如果用户想打印链表里面的数据,就必须知道链表的内部结构(即结点的每个域的名字及作用)
// 这就①增加了使用成本②破坏了封装性
//所以就产生了迭代器这个东西。
template<class T,class ref,class ptr>
struct ListIterator //迭代器就是为了方便访问容器里面的数据(迭代器有点像智能指针)
{//链表的迭代器
typedef ListIterator<T, ref, ptr> self;
typedef listnode<T> Node;
typedef ref Refence;//使Refence为ref的别名,如果外面要用Refence,就必须通过ListIterator<T,ref,ptr>或者它的别名来访问
typedef ptr Pointer;
Node * _node; //其实就是迭代器的数据成员_node在指向结点
ListIterator(Node *node)//构造函数
:_node(node)
{}
//不用写默认的拷贝构造函数+赋值运算符重载函数,因为迭代器的对象要像普通指针一样,默认的就已经满足要求了。
//要能像普通指针一样能访问链(重载++ -- * -> != ==)
ref operator*()//_data是个普通类型(像指向内置类型的普通指针一样解引用就得到它指向的数据)
{
return _node->_data;
}
ptr operator->()//假如_data是个自定义类型(eg.是个结构体)(像指向自定义类型的普通指针一样)
{
return &(_node->_data);//必须返回对象的指针(即该对象的指针)****或返回自定义了箭头运算符的某个类的对象
}
self& operator++()//像普通指针一样前置自增
{
_node = _node->_next;
return *this;
}
self operator++(int)//像普通指针一样后置自增
{
self tmp(*this);
_node = _node->_next;
return tmp;
}
self& operator--()//像普通指针一样前置自减
{
_node = _node->_prev;
return *this;
}
self operator--(int)//像普通指针一样后置自减
{
self tmp(*this);
_node = _node->_prev;
return tmp;
}
bool operator != (const self& s)
{
return _node != s._node;
}
bool operator == (const self& s)
{
return _node == s._node;
}
};
//该链表是带头双向循环链表
template<class T>
class Mylist
{
typedef listnode<T> node;
node* _head; //头结点指针
public:
typedef ListIterator<T, T&, T*> Iterator; //这个typedef还必须放在公有下,因为该迭代器要在外面用
typedef ListIterator<T, const T&, const T*> ConstIterator;
typedef ReverseIterator5<Iterator> ReverseIterator;//反向迭代器
typedef ReverseIterator5<ConstIterator> Const_ReverseIterator;
Mylist()//默认构造函数,
:_head(new node(T()))
{
_head->_next = _head;
_head->_prev = _head;
}
//深拷贝构造+赋值运算符重载(要写,深浅拷贝问题)
//Mylist的迭代器的begin和end
Iterator Begin()//迭代器就是让它的对象封装了一个结点指针
{
return Iterator(_head->_next);
}
ConstIterator Begin()const//常成员函数:关键是编译器不允许它修改调用它的对象的数据成员。
{
return ConstIterator(_head->_next);
}
ReverseIterator RBegin()//反向迭代器指向的第一个元素
{
return End();
}
//Const_ReverseIterator RBegin()const//反向迭代器指向的第一个元素
//{
// return End();
//}
Iterator End()
{
return Iterator(_head);
}
ConstIterator End()const//然后常对象只能调用常成员函数。
{
return ConstIterator(_head);
}
ReverseIterator REnd()//反向迭代器指向的最后一个元素
{
return Begin();
}
//Const_ReverseIterator REnd()const//反向迭代器指向的最后一个元素
//{
// return Begin();
//}
//增删 查改
void Pushback(const T& x)
{
node *tmp = new node(x);
_head->_prev->_next = tmp;
tmp->_prev = _head->_prev;
tmp->_next = _head;
_head->_prev = tmp;
}
void Pushfront(const T& x)
{
node *tmp = new node(x);
_head->_next->_prev = tmp;
tmp->_next = _head->_next;
tmp->_prev = _head;
_head->_next = tmp;
}
void Popback()
{
node *tmp = _head->_prev;
_head->_prev = tmp->_prev;
tmp->_prev->_next = _head;
delete tmp;
}
void Popfront()
{
node *tmp = _head->_next;
_head->_next = tmp->_next;
tmp->_next->_prev = _head;
}
void Insert(Iterator pos,const T& x)//pos就是一个迭代器的对象,它里面有一个结点指针
{
node *cur = pos._node;
node *tmp = new node(x);
cur->_prev->_next = tmp;
tmp->_prev = cur->_prev;
tmp->_next = cur;
cur->_prev = tmp;
}
Iterator Erase(Iterator pos)
{
assert(pos != End());
node *prev = (pos._node)->_prev;
node *next = (pos._node)->_next;
prev->_next = next;
next->_prev = prev;
delete pos._node;
return Iterator(next);
//return next;//隐式类型转换
}
Iterator Erase2(Iterator& pos)//改进:解决了迭代器失效的问题
{
assert(pos != End());
node *prev = (pos._node)->_prev;
node *next = (pos._node)->_next;
prev->_next = next;
next->_prev = prev;
delete pos._node;
pos = prev;//感觉有点问题。
return Iterator(next);
//return next;//隐式类型转换
}
};
myReverseIterator.h
#pragma once
//反向迭代器是通过正向迭代器适配出来的
template<class Iterator>//模板参数(Iterator是一个类型)
struct ReverseIterator5 //(ReverseIterator5<Iterator>是一个类型)
{
Iterator _it;
ReverseIterator5(Iterator it)
:_it(it)
{}
typename Iterator::Refence operator*()//类型里面的类型Refence Pointer
{
Iterator it = _it;
return *(--it);
}
typename Iterator::Pointer operator->()
{
return &(operator*());
}
ReverseIterator5 operator++()
{
--_it;
return *this;
}
ReverseIterator5 operator--()
{
++_it;
return *this;
}
bool operator != (ReverseIterator5<Iterator>& s)
{
return _it != s._it;
}
bool operator == (ReverseIterator5<Iterator>& s)
{
return _it == s._it;
}
};
test.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<CoreWindow.h>
#include<assert.h>
#include"mylist.h"
template<class T>
void Printlist(const Mylist<T>& l)
{
Mylist<T>::ConstIterator it = l.Begin();
while (it != l.End())
{
cout << *it << " ";
++it;
}
cout << endl;
}
void testlist()
{
Mylist<int> l;
l.Pushback(1);
l.Pushback(2);
l.Pushback(6);
l.Pushback(4);
l.Pushback(5);
Printlist(l);
Printlist2(l);
}
int main()
{
testlist();
system("pause");
return 0;
}