list

  list不能像vector那样以普通指针作为迭代器,因为其节点不保证在储存空间中连续存在。因为要保证迭代器能进行operator++, operator--,所以STL list是一个双向链表。

  list比vector好的地方在于,插入操作(insert)和接合操作(splice)都不会使原有的迭代器失效。(上一篇介绍过,vector会在扩充空间时使得原有迭代器失效)。但是删除操作(erase)还是会使”指向被删除元素“的那个迭代器失效。


  list的节点结构如下:  

	template <class T>
	struct __list_node {
		typedef void* void_pointer;
		void_pointer prev; 	//型别为void*,其实可设为__list_node<T>*
		void_pointer next;
		T data;
	}

  list的数据结构如下:

	template < class T, class Alloc = alloc>
	class list {
	protected:
		typedef __list_node<T> list_node;
	public:
		typedef list_node* link_type;
	protected:
		link_type node;		// 只要一个指针,便可表示完整的环状双向链表
	}
  值得一提的是,list不仅是一个双向链表,而且还是一个环状双向链表,所以它只需要一个指针,就可以完整表现整个链表。而且会使node指向刻意置于尾端的一个空白节点,这样就能符合STL对于”前闭后开“的区间要求。

  如此一来,list的几个成员函数便可以很简单的实现:

	iterator begin() 	{ return (link_type)((*node).next); }
	iterator end() 		{ return node; }
	bool empty() const 	{ return node->next == node; }

   list的push_back(), push_front()都是调用的insert(),pop_front(), pop_back()都是调用erase(), 这些操作都双向链表来说都是相当简单的。

  值得注意的是,list内部提供一个非公开的接口transfer(iterator pos, iterator i, iterator j),把[i, j)内的所有元素移到pos之前。这个函数在list内部发挥了重要的作用。

  splice()函数把某连续范围的元素从一个List移到另一个(或同一个)list的某个定点,它内部只是简单调用transfer()而已。

  merge(list& x)把另一个list合并到*this中,但前提是两个list都必须先经过递增排序,并在合并后保持递增顺序。如果不关心排序,就用splice()好了。

  reverse()从第二个结点开始,循环调用transfer(),每次把一个结点移动到头结点前面,以实现反向。

  sort()使用快速排序法,并在内部使用到splice()。注意list不能使用STL的算法sort(),必须使用自己的成员函数sort(),因为STL算法sort()只接受RamdonAccessIterator.





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值