#include <iostream>
using namespace std;
template<class _Ty>
class List
{
protected:
struct _Node;//先声明一个节点类型的结构体,在下一行进行重命名
typedef _Node* _Nodeptr;//这里重命名为_Nodeptr,别名之后可以通过名字知道他是一个指向结构体的指针
struct _Node {
_Nodeptr _Next, _Prev;
_Ty _Value;
};//std标准给的list是双向链表,该结构体中存储的是该节点的前驱和后继
struct _Acc {
typedef _Nodeptr& _Nodepref;
typedef _Ty& _Vref;
static _Nodepref _Next(_Nodeptr _P) {
return ((_Nodepref)(*_P)._Next);
}
static _Nodepref _Prev(_Nodeptr _P) {
return ((_Nodepref)(*_P)._Prev);
}
static _Vref _Value(_Nodeptr _P) {
return ((_Vref)(*_P)._Value);
}
};//该结构体中有三个方法,分别返回节点的前驱,后继。因为我们一般取前驱的时候是node->prev,重点在node上,而该方法调用的时候是 _Acc::_Prev(node),我们先看到的是Prev。侧重点是前驱。
public:
class iterator {//内部类
public:
iterator() {}//迭代器的无参构造
iterator(_Nodeptr _P) :_Ptr(_P) {}//通过指针构造迭代器
_Ty& operator*()const {
return (_Acc::_Value(_Ptr));
}//重载*运算符,使得当我们*iterator的时候可以获得当前迭代器指向节点的值
iterator& operator++() {
_Ptr = _Acc::_Next(_Ptr);
return *this;
}//重载前置++,返回下一个节点的位置
iterator operator++(int) {
iterator _Tmp = *this;
++* this;
return _Tmp;
}//重载后置++,返回当前节点。但是迭代器已经+1
iterator& operator--() {
_Ptr = _Acc::_Prev(_Ptr);
return *this;
}//同前置++
iterator operator--(int) {
iterator _Tmp = *this;
--* this;
return _Tmp;
}//同后置++
bool operator==(const iterator& _X) {
return _Ptr == _X._Ptr;
}//重载==号,返回是否相等
bool operator!=(const iterator& _X) {
return (!(*this == _X));
}//重载!=号
_Nodeptr _Mynode()const {
return (_Ptr);
}//获取当前节点的节点位置
protected:
_Nodeptr _Ptr;//每个迭代器其实内部都是结构体指针
};
public://构造函数
explicit List():_Head(_Buynode()),_Size(0)
{}//无参构造函数
explicit List(size_t _N, const _Ty& _V = _Ty()) :_Head(_Buynode()), _Size(0) {
insert(begin(), _N, _V);
}//通过元素和元素数量构造 记为构造1
List(const _Ty* _F, const _Ty* _L):_Head(_Buynode()),_Size(0) {
insert(begin(), _F, _L);
}//通过数组构造链表 记为 构造2
typedef iterator _It;//重命名迭代器为_It
List(_It _F, _It _L) : _Head(_Buynode()), _Size(0)
{
insert(begin(), _F, _L);
}//通过迭代器构造链表 记为构造3
public:
void insert(iterator _P, _It _F, _It _L) {
for (; _F != _L; ++_F) {
insert(_P, *_F);//调用底层insert函数
}构造3的insert
}//
void insert(iterator _P, const _Ty* _F, const _Ty* _L) {
for (; _F != _L; ++_F) {
insert(_P, *_F);//调用底层构造函数
}
}//构造2的insert
void insert(iterator _P, size_t _M, const _Ty& _X)
{
for (; _M > 0; _M--) {
insert(_P, _X);//调用底层构造函数
}
}//构造3的insert
iterator insert(iterator _P, const _Ty& _X = _Ty()) {
_Nodeptr _S = _P._Mynode();
_Acc::_Prev(_S) = _Buynode(_S, _Acc::_Prev(_S));
_S = _Acc::_Prev(_S);
_Acc::_Next(_Acc::_Prev(_S)) = _S;
_Acc::_Value(_S) = _X;
++_Size;
return (iterator(_S));
}//队链表进行插入的时候底层都是
iterator begin()
{
return (iterator(_Acc::_Next(_Head)));
}//获取当前起始节点的迭代器,即结点指针封装后的迭代器。双链表头结点的后继就是起始节点
iterator end()
{
return (iterator(_Head));
}//头节点就是最后一个节点的指向
void push_front(const _Ty& _X)
{
insert(begin(), _X);
}//在链表头部插入元素,就是在第一个元素的位置插入
void push_back(const _Ty& _X)
{
insert(end(), _X);
}//在头节点位置插入的时候就是尾插
protected:
_Nodeptr _Buynode(_Nodeptr _Narg = 0, _Nodeptr _Parg = 0) {
_Nodeptr _T = (_Nodeptr)malloc(1 * sizeof(_Node));
_Acc::_Next(_T) = _Narg != 0 ? _Narg : _T;
_Acc::_Prev(_T) = _Parg != 0 ? _Parg : _T;
return(_T);
}//每次构造一个节点,并通过传入的元素初始化该节点
protected:
_Nodeptr _Head;//链表的元素包括头节点
size_t _Size;//链表的大小
};
int main()
{
List<int> l1;
List<int> l2(5, 6);
int arr[5] = { 0,1,2,3,4 };
List<int>::iterator iter;
List<int> l3(arr, arr + 5);//_Ty*
List<int> l4(l2.begin(),l2.end());
l3.push_back(9999);
l3.push_front(8888);
for (iter = l3.begin(); iter != l3.end(); iter++)
{
cout << *iter << " ";
}
return 0;
}
C++ 仿写 std::list
于 2023-06-07 01:17:06 首次发布