LIST源码解析

目录

构造函数

析构函数

结点:

创建结点

_ACC找结点的三个域

插入

插入的三种方式

删除结点

其他基于插入删除的函数

运算符重载

与size有关的函数


开头定义一个模板

allocator:空间配置器,负责开辟空间

template<class _Ty, class _A = allocator<_Ty> >

构造函数

构造函数一共三个

list(const _Myt& _X)
: allocator(_X.allocator),_Head(_Buynode()), _Size(0)//构建头节点
{
    insert(begin(), _X.begin(), _X.end());//插入
}
list(const _Ty *_F, const _Ty *_L, const _A& _Al = _A())
: allocator(_Al),_Head(_Buynode()), _Size(0)//构建头节点
{
    insert(begin(), _F, _L);
}
typedef const_iterator _It;
list(_It _F, _It _L, const _A& _Al = _A())
: allocator(_Al),_Head(_Buynode()), _Size(0)//构建头节点
{
    insert(begin(), _F, _L); 
}

析构函数

~list()
{
//从头删到尾
    erase(begin(), end());
//释放结点
	_Freenode(_Head);
//大小置0
	_Head = 0, _Size = 0;
 }

结点:

        双向链表,包含指向下一个结点的指针、指向当前结点的指针,和当前结点的值。

struct _Node 
{
	_Nodeptr _Next, _Prev;//后,前指针
	_Ty _Value;//值
};

_Nodeptr是指向node的指针类型

typedef _POINTER_X(_Node, _A) _Nodeptr;

创建结点

在此假设当前结点为p,传入p和p->prev。

创建一个结点S,目标是把S插入到p前面(头插)(如果p是空说明S作为头节点)。

//传当前结点(p,p->prev)
_Nodeptr _Buynode(_Nodeptr _Narg = 0, _Nodeptr _Parg = 0)
{
    //开空间_S
    _Nodeptr _S = (_Nodeptr)allocator._Charalloc(1 * sizeof (_Node));
    //p若不等于空,_S->next = p,否则,_S->next指向_S
	_Acc::_Next(_S) = _Narg != 0 ? _Narg : _S;
    //p->prev若不等于空,_S->prev= p->prev,否则,指向_S。
	_Acc::_Prev(_S) = _Parg != 0 ? _Parg : _S;
	return (_S);
 }

_ACC找结点的三个域

使用static静态可以不用使用对象直接用成员函数,如: _Acc::_Next(_P) == _P->next

struct _Acc 
{
//node结点p指针ref引用,结点指针的引用
	typedef _REFERENCE_X(_Nodeptr, _A) _Nodepref;
//值类型的引用
	typedef _A::reference _Vref;
//返回指向的下一个结点的指针
	static _Nodepref _Next(_Nodeptr _P)
	{
        return ((_Nodepref)(*_P)._Next); 
    }
//返回指向的(_P)前一个结点(_P->prev)的指针
	static _Nodepref _Prev(_Nodeptr _P)
	{
        return ((_Nodepref)(*_P)._Prev);
    }
//返回_P指向的值
	static _Vref _Value(_Nodeptr _P)
	{
        return ((_Vref)(*_P)._Value); 
    }
};

插入

//迭代器_P,值_X
iterator insert(iterator _P, const _Ty& _X = _Ty())
{
//把迭代器转成指针指向当前结点
    _Nodeptr _S = _P._Mynode();
//_S的前驱指向新创建的一个结点(在Buynode中这个新创建的结点)
	_Acc::_Prev(_S) = _Buynode(_S, _Acc::_Prev(_S));
//_S指向刚才创建的结点
	_S = _Acc::_Prev(_S);
//_S->prev->next = _S
	_Acc::_Next(_Acc::_Prev(_S)) = _S;
	allocator.construct(&_Acc::_Value(_S), _X);
	++_Size;//个数++
	return (iterator(_S)); 
}

插入的三种方式

在p位置插入M个x

在p位置插入_F到_L的数据(指针、值传递)

void insert(iterator _P, size_type _M, const _Ty& _X)
{
	for (; 0 < _M; --_M)
	insert(_P, _X);//每次都是在_P的位置插(头插)
}
void insert(iterator _P, const _Ty *_F, const _Ty *_L)//指针传递
{
    for (; _F != _L; ++_F)
	insert(_P, *_F);
 }
void insert(iterator _P, _It _F, _It _L)//值传递
{
    for (; _F != _L; ++_F)
    insert(_P, *_F);
 }

删除结点

iterator erase(iterator _P)
{
	_Nodeptr _S = (_P++)._Mynode();
//_S->prev->next = _S->next
	_Acc::_Next(_Acc::_Prev(_S)) = _Acc::_Next(_S);
//_S->next->prev = _S->prev
	_Acc::_Prev(_Acc::_Next(_S)) = _Acc::_Prev(_S);
	allocator.destroy(&_Acc::_Value(_S));//销毁_S结点
	_Freenode(_S);//释放
	--_Size;//结点个数减一
	return (_P);
}
//删除多个结点F到L
iterator erase(iterator _F, iterator _L)
{
	while (_F != _L)
	erase(_F++);
    	return (_F);
}

其他基于插入删除的函数

//头入
void push_front(const _Ty& _X)
{insert(begin(), _X); }
//头出
void pop_front()
{erase(begin()); }
//尾插
void push_back(const _Ty& _X)
{insert(end(), _X); }
//尾出
void pop_back()
{erase(--end()); }
//重新赋值
void assign(_It _F, _It _L)
{
    erase(begin(), end());//删去所有
    insert(begin(), _F, _L);//插
 }
void assign(size_type _N, const _Ty& _X = _Ty())
{
    erase(begin(), end());
	insert(begin(), _N, _X); 
}

运算符重载

		const_reference operator*() const
		{
			return (_Acc::_Value(_Ptr)); 
		}
		_Ctptr operator->() const
		{
			return (&**this); 
		}
		const_iterator& operator++()	
		{
			_Ptr = _Acc::_Next(_Ptr);
			return (*this);
		}
		const_iterator operator++(int)
		{
			const_iterator _Tmp = *this;
			++*this;
			return (_Tmp);
		}
		const_iterator& operator--()
		{
			_Ptr = _Acc::_Prev(_Ptr);
			return (*this); 
		}
		const_iterator operator--(int)
		{
			const_iterator _Tmp = *this;
			--*this;
			return (_Tmp);
		}
		bool operator==(const const_iterator& _X) const
			{return (_Ptr == _X._Ptr); }
		bool operator!=(const const_iterator& _X) const
			{return (!(*this == _X)); }
		_Nodeptr _Mynode() const
			{return (_Ptr); }
	protected:
		_Nodeptr _Ptr;


与size有关的函数

//重新赋大小
void resize(size_type _N, _Ty _X = _Ty())
{
    if (size() < _N)//原本的小,给结尾插 _N - size()个_X
		insert(end(), _N - size(), _X);
	else//否则出栈
		while (_N < size())
			pop_back();
 }
//取大小
size_type size() const
{return (_Size); }
//最大
size_type max_size() const
{return (allocator.max_size()); }
//判空
bool empty() const
{return (size() == 0); }

未完待续

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曦樂~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值