STL之list函数详解

List结构

list使用双向链表来管理元素,可以从两端发展新元素,其内部结构如图1所示。
          
图1 list的结构

List能力

List的内部结构和vetor或deque截然不同,主要的区别入下:
  • list不支持随机存取功能,可以支持首尾的直接存取,想获取其他元素,则需要遍历链表。
  • 任何位置的删除、插入操作都非常快速,不需要移动和删除其他元素,这些操作在常数时间内完成。
  • 安插和删除操作不会造成指向其他元素的各个pointer、reference、iterators失效
  • list对异常操作的处理方式:要么成功,要么什么都不发生。
List所提供的成员函数区别
  • list提供了不少特殊的成员函数,专门用于移动元素,和STL的通用算比较,这些成员函数的执行速度更快,主要是成员函数操作时,不需要移动元素或拷贝,仅需要调指针。

Splice函数

list的好处是不论在任何位置,元素的安插和移除都只需要常数时间。如果我们要将若干元素从A容器移动B容器,使用splice函数将会更加高效,splice中文解释为衔接,链接,结合。从名字中就可以看出,该函数的功能,如图2所示是将元素3从容器A转移到容器B中,C之前(举例用,未考虑型别),从执行动作中,可以看到执行splice函数后,原容器中就不包含该元素了,是转移属于操作

图2 splice举例

List操作函数族

list类提供了多种操作元素的函数和算法,这些函数可以满足大部分的应用场景。

List的构造函数和析构函数
list<Elem> c 产生一个空list,其中没有任何元素
list<Elem> c1(c2) 产生另一个同型list的副本(所有的元素都被拷贝)
list<Elem> c(n) 利用元素的default构造函数产生一个大小为n的list
list<Elem> c(n,elem) 产生一个大小为n的list,每个元素值都是elem
list<Elem> c(beg, end) 产生一个list,以区间[beg, end)做为元素初值
c.~list<Elem>() 销毁所有元素,并释放内存
list的非变动性操作
c.size() 返回容器的大小
c.empty() 判断容器是否为空,等价于size()==0,但可能更快
c.max_size() 返回容器最大的可以存储的元素
reserve() 如果容量不足,扩大之
c1 == c2 判断c1 是否等于c2
c1 != c2 判断c1是否不等于c2
c1 < c2 判断c1 是否小于c2
c1 > c2 判断c1 是否大于c2
c1 <= c2 判断c1是否小于等于c2
c1 >= c2 判断c1是否大于等于c2
list的赋值操作
c1 = c2 将c2的全部元素赋值给c1
c.assign(n, elem) 复制n个elem,复制给c
c.assign(beg, end) 将区间[beg;end)内的元素赋值给c
c1.swap(c2) 将c1和c2元素互换
swap(c1,c2) 同上,此为全局函数
list元素之间存取
c.front 返回第一个元素,不检查元素存在与否
c.back 返回最后一个元素,不检查元素存在与否
list迭代器相关函数
c.begin() 返回一个双向迭代器,指向第一个元素
c.end() 返回一个双向迭代器,指向最后一个元素的下一个位置
c.begin() 返回一个逆向迭代器,指向逆向迭代的第一个元素
c.end() 返回一个逆向迭代器,
指向逆向迭代的最后一个元素的下一个位置
list安插、移除操作函数
c.insert(pos, elem) 在迭代器pos所指位置上安插一个elem副本,
并返回新元素的位置
c.insert(pos,n,elem) 在pos位置上插入n个elem副本,无返回值
c.insert(pos,beg,end) 在pos位置上插入区间[beg,end)内的所有元素的副本
没有返回值
c.push_back(elem) 在尾部添加一个elem副本
c.pop_back() 移除最后一个元素,无返回值
c.push_front() 在头部添加一个elem副本
c.pop_front() 移除第一个元素,但不返回
c.remove(val) 移除所有其值为val的元素
c.remove_if()
c.erase(pos) 移除pos位置上的元素,返回下一个元素的位置
c.erase(beg, end) 移除[beg, end)区间内的所有元素,
返回下一个元素的位置
c.resize(num) 将元素数量改为num(如果size()变大了,
多出来的新元素都需以default构造函数完成)
c.resize(num,elem) 将元素数量改为num(如果size()变大了,
多出来的新元素都elem的副本)
c.clear() 移除所有元素,将容器清空
备注:安插和移除元素,都会使“作用点”之后的各个元素的iterator等失效,若发生内存重新分配,该容器身上的所有iterator等都会失效
List的特殊变动性操作
c.unique() 如果存在若干相邻而数值相等的元素,就移除重复元素,
之留下一个
c.unique(op) 如果存在若干相邻元素,都使op()的结果为ture,
则移除重复元素,只留下一个。
c1.splice(pos, c2) 将c2内的所有元素转移到c1之内,迭代器pos之前
c1.splice(pos, c2, c2pos) 将c2内的c2pos所指元素转移到c1之内的pos所指位置上
(c1,c2可相同)
c1.splice(pos, c2,
         c2beg,c2end)
将c2内的[c2beg,c2end)区间内所有元素转移到
c1内的pos之前(c1,c2可相同)
c.sort() 以operator<为准则,对所有元素排序
c.sort(op) 以op()为准则,对所有元素排序
c1.merge(c2) 假设c1和c2容器都包含已序(相同的排序方式)元素,将c2的全部元素转移到c1,并保证合并后的list还是已序。
c1.merge(c2,op) 假设c1和c2容器都包含op()原则下的已序(相同的排序方式)元素,将c2的全部元素转移到c1,并保证合并后的list在op()原则仍是已序。
c.reverse() 将所有元素反序

list实例

#include "stdafx.h"
#include <list>
#include <string>
#include <iostream>
#include <algorithm>

using namespace std;

void PrintLists(const list<int> &list1, const list<int> &list2)
{
	cout << "list1: ";
	copy(list1.begin(), list1.end(), ostream_iterator<int>(cout ," "));

	cout << endl << "list2: ";
	copy(list2.begin(), list2.end(), ostream_iterator<int>(cout, " "));
	cout << endl;
	cout << endl;
}

void ListExample()
{
	//creat two empty lists;
	list<int> list1, list2;

	for (int i = 0; i < 6;  ++i)
	{
		list1.push_back(i);
		list2.push_front(i);
	}
	
	//list1: 0 1 2 3 4 5 //list2: 5 4 3 2 1 0 
	PrintLists(list1, list2);

	list2.splice(find(list2.begin(), list2.end(), 3), list1);
	PrintLists(list1, list2);

	list2.splice(list2.end(), list2, list2.begin());
	PrintLists(list1, list2);

	list2.sort();
	list1 = list2;
	//list1.push_back(-9);

	list2.unique();
	PrintLists(list1, list2);

	list1.merge(list2);
	PrintLists(list1, list2);

	list1.reverse();
	PrintLists(list1, list2);
	
}
调用ListExample函数后的运行结果:
posted @ 2016-05-05 22:19  小怪兽&奥特曼  阅读(607)  评论(0编辑  收藏  举报