C++——List

 


 
 

  
List图示
list 包含在头文件< list >中:

#include <list>

其中的 list 类型系定义于 namespace std 中,是个 class template:

namespace std {
	template <typename T,
				typename Allocator = allocator<T> >
			class list;
}

List 的元素可以是任何类型 T。第二个 template 实参可有可无,用来指定内存模型。默认的内存模型是 C++ 标准库提供的 allocator。

 
 

 
 

 
 

List 的能力

  List 的内部结构完全迥异于 array、vector 或 deque。List 对象自身提供了两个 pointer,或称 anchor (锚点),用来指向第一个和最末一个元素。每个元素都有 pointer 指向前一个和下一个元素(或是指回 anchor)。如果想要安插新元素,只需操纵对应的 pointer即可(如下图所示)。
追加图示
因此,list 在几个主要方面与 array、 vector 或 deque 不同:

  • List 不支持随机访问。如果你要访问第 5 个元素,就得顺着串链逐一爬过前 4 个元素。所以,在 list 中随机巡访任意元素是很缓慢的行为。然而你可以从两端开始航行整个 list,所以访问第一个或最末一个元素的速度很快。
  • 任何位置上(不只两端)执行元素的安插和移除都非常快,始终都是常量时间内完成,因为无须移动任何其他元素。实际上内部只是进行了一些 pointer 操作而已。
  • 安插和删除动作并不会造成指向其他元素的各个 pointer、reference 和 iterator 失效。
  • List 对于异常的处理方式是:要么操作成功,要么什么都不发生。你绝不会陷入“只成功一半”这种进退维谷的尴尬境地。

 
 
List 所提供的成员函数反映出它和 array、vector 以及 deque 的不同:

  • List 提供 front()、 push_front() 和 pop_front()、back()、 push_back() 和 pop_back() 等操作函数。
  • 由于不支持随机访问,list 既不提供 subscript (下标)操作符,也不提供 at()。
  • List 并未提供容量、空间重新分配等操作函数,因为全无必要。每个元素有自己的内存,在元素被删除前一直有效。
  • List 提供不少特殊成员函数,专门用于移动和移除元素。较之同名的 STL 通用算法,这些函数执行起来更快速,因为它们无须复制或搬移元素,只需调整若干 pointer 即可。

 
 

 
 

 
 

List 构造

操作描述
list< Elem > cDefault 构造函数,产生一个空 list,没有任何元素
list< Elem > c(c2)Copy 构造函数,建立 c2 的同型 list 并成为 c2 的一份拷贝(所有元素都被复制)
list< Elem > c = c2Copy 构造函数,建立一个新的 list 作为 c2 的拷贝(每个元素都被复制)
list< Elem > c(rv)Move 构造函数,建立一个新的 list,取 rvalue rv 的内容(始自 C++11)
list< Elem > c = rvMove 构造函数,建立一个新的 list,取 rvalue rv 的内容(始自 C++11)
list< Elem > c(n)利用元素的 default 构造函数生成一个大小为 n 的 list
list< Elem > c(n, elem)建立一个大小为 n 的 list,每个元素值都是 elem
list< Elem > c(beg, end)建立一个 list,以区间 [beg, end) 作为元素初值
list< Elem > c(initlist)建立一个 list,以初值列 initlist 的元素为初值(始自 C++11)
list< Elem > c = initlist建立一个 list,以初值列 initlist 的元素为初值(始自 C++11)
c.~list()销毁所有元素,释放内存

 
 

 
 

 
 

非更易型操作

操作描述
c.empty()返回是否容器为空(相当于 size() == 0 但也许较快
c.size()返回目前的元素个数
c.max_size()返回元素个数之最大可能量
c1 ==c2返回 c1 是否等于 c2 (对每个元素调用 ==)
c1 != c2返回 c1 是否不等于 c2(相当于 !(c1 == c2))
c1 < c2返回 c1 是否小于 c2
c1 > c2返回 c1 是否大于 c2(相当于 c2 < c1)
c1 <= c2返回 c1 是否小于等于 c2 (相当于 !(c2 < c1) )
c1 >= c2返回 c1 是否大于等于 c2(相当于 !(c1 < c2))

 
 

 
 

 
 

List 赋值操作

操作描述
c = c2将 c2 的全部元素赋值给 c
c = rv将 rvalue rv 的所有元素以 move assign 方式给予 c (始自 C++11)
c = initlist将初值列 initlist 的所有元素赋值给 c (始自 C++11)
c.assign(n,elem)复制 n 个 elem,赋值给 c
c.assign(beg , end)将区间 [beg, end) 内的元素赋值给 c
c.assign(initlist)将初值列 initlist 的所有元素赋值给 c
c1.swap( c2)置换 c1 和 c2 的数据
不抛出异常
swap(c1 , c2)置换 c1 和 c2 的数据
不抛出异常

 
 

 
 

 
 

List 访问

操作描述
c.front()返回第一元素(不检查是否存在第一元素)
c.back()返回最末元素(不检查是否存在最末元素)

 
 

 
 

 
 

迭代器相关操作

操作描述
c.begin()返回一个 bidirectional iterator 指向第一元素
c.end()返回一个bidirectional iterator 指向最末元素的下一位置
c.cbegin()返回一个 const bidirectional iterator 指向第一元素(始自 C++11)
c.cend()返回一个 const bidirectional iterator 指向最末元素的下一位置(始自 C++11)
c.rbegin()返回一个反向的( reverse ) iterator 指向反向迭代的第一元素
c.rend()返回一个反向的( reverse ) iterator 指向反向迭代的最末元素的下一位置
c.crbegin()返回一个 const reverse iterator 指向反向迭代的第一元素(始自 C++11)
c.crend()返回一个 const reverse iterator 指向反向迭代的最末元素的下一位置(始自 C++11)

 
 

 
 

 
 

元素的安插和移入

操作描述
c.push_back(elem)附加一个 elem 的拷贝于未尾
要么成功,要么无任何作用(no effect )
c.pop_back()移除最后一个元素,但是不返回它
不抛出异常
c.push_front(elem)在头部插入 elem 的一个拷贝
要么成功,要么无任何作用(no effect)
c.pop_front()移除第一元素(但不返回)
不抛出异常
c.insert(pos , elem)在 iterator 位置 pos 之前方插人一个 elem 拷贝,并返回新元素的位置
要么成功,要么无任何作用(no effect)
c.insert(pos ,n ,elem)在 iterator 位置 pos 之前方插入 n 个 elem 拷贝,并返回第一个新元素的位置(或返回 pos——如果没有新元素的话)
要么成功,要么无任何作用(no effect)
c.insert(pos , beg , end)在 iterator 位置 pos 之前方插入区间 [beg, end) 内所有元素的一份拷贝,并返回第一个新元素的位置(或返回 pos——如果没有新元素的话)
要么成功,要么无任何作用(no effect)
c.insert(pos , initlist)在 iterator 位置 pos 之前方插入初值列 initlist 内所有元素的一份拷贝,并返回第一个新元素的位置(或返回 pos—如果没有新元素的话;始自 C++11)
要么成功,要么无任何作用(no effect)
c.emplace(pos , args . . .)在 iterator 位置 pos 之前方插入一个以 args 为初值的元素,并返回新元素的位置(始自C++11)
c.emplace_back(args . . .)附加一个以 args 为初值的元素于未尾,不返回任何东西(始自 C++11)
c.emplace_front(args . . .)插入一个以 args 为初值的元素于起点,不返回任何东西(始自 C++11)
c.erase(pos)移除 iterator 位置 pos 上的元素,返回下一元素的位置
不抛出异常
c.erase(beg , end)移除 [beg, end) 区间内的所有元素,返回下一元素的位置
不抛出异常
c.remove(val)移除所有其值为 val 的元素
只要元素比较动作不抛出异常,它就不抛出异常
c.remove_if(op)移除所有“造成 op (elem)结果为 true”的元素
只要判断式(predicate)不抛出异常,它就不抛出异
c.resize(num)将元素数量改为 num (如果 size() 变大,多出来的新元素都需以 default 构造函数完成初始化)
要么成功,要么无任何作用(no effect)
c.resize(num , elem)将元素数量改为 num (如果 size() 变大,,多出来的新元素都是 elem 的拷贝)
要么成功,要么无任何作用(no effect)
c.clear()移除所有元素,将容器清空
不抛出异常

 
 

 
 

 
 

特殊更易型操作

操作描述
c.unique()如果存在若干相邻而数值相同的元素,就移除重复元素,只留一个
只要元素比较动作不抛出异常,它就不抛出异常
c.unique(op)如果存在若干相邻元素都使 op() 的结果为 true,则移除重复元素,只留一个
只要元素比较动作不抛出异常,它就不抛出异常
c.splice(pos , c2)将 c2 内的所有元素转移(move)到 c 之内、迭代器 pos 之前
不抛出异常
c.splice(pos , c2 , c2pos)将 c2 内的 c2pos 所指元素转移到 c 内的 pos 所指位置( c 和 c2 可相同)
不抛出异常
c.splice(pos , c2, c2beg , c2end)将 c2 内的 [c2beg, c2end) 区间内所有元素转移到 c 内的 pos 之前( c 和 c2 可相同)
不抛出异常
c.sort()以 operator < 为准则对所有元素排序
c.sort(op)以 op() 为 i 准则对所有元素排序
c.merge(c2)假设 c 和 c2 容器都包含 op() 准则下的已排序(sorted)元素,将 c2 的全部元素转移到 c,并保证合并后的 list 仍为已排序
只要元素比较时不抛出异常,它便保证“要么成功,要么无任何作用”
c.merge(c2 , op)假设 c 和 c2 容器都包含已排序(sorted)元素,将 c2 的全部元素转移到 c,并保证合并后的 list 在 op() 准则下仍为已排序
只要元素比较时不抛出异常,它便保证“要么成功,要么无任何作用”
c.reverse()将所有元素反序(reverse the order)
不抛出异常

 
 

 
 

 
 

实例

#include <iostream>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;

void printList(const list<int>& l){
	printf("list: ");
	copy(l.cbegin(), l.cend(), ostream_iterator<int>(cout, " "));
	printf("\n");
}

int main()
{
	list<int> l1, l2;
	for(int i = 0; i < 6; i ++){
		l1.push_back(i);
		l2.push_front(i);
	}
	printList(l1);
	printList(l2);
	
	printf("\n");
	l2.splice(l2.end(), l1);
	printList(l1);
	printList(l2);
	
	l2.splice(l2.end(), l2, l2.begin());
	printList(l2);
	
	printf("\n");
	l2.sort();//排序 
	l1 = l2;
	printList(l1);
	l2.unique();//去重排序 
	printList(l2);
	
	printf("\n");
	l1.merge(l2);//合并,同时排序 
	printList(l1);
	printList(l2); 
	return 0;
}

运行结果

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值