【STL】list简介

一、简介

list是一个双向链表,支持快双向顺序访问。在链表最后中任何位置进行元素插入 /删除的速度都是非常迅速的。

与vector和array不同,list中的元素可以存放在多个不同的且没有联系的存储空间当中,通过每个元素到他前面一个元素的链接和到他后面一个元素的链接来实现顺序访问。因为list的元素存放位置比较分散,所以不支持下标操作符。所以要对list容器当中的元素进行遍历,需要使用list对应的迭代器。

也正是因为list容器当中的元素存放在多个不同的切没有联系的存储空间当中,list具备了其他顺序容器(如:vector,deque,array)不具有的独有特性:在容器任意位置删除/插入元素都非常的方便。同时也具备了其他顺序容器不具备的sort、remove、unique、merge、reverse等不具备的操作。

但是,list也有它的缺点:list对元素的访问只能通过迭代器来实现,且迭代器不能直接跳到我们需要访问的元素的那个位置,必须从begin 或者 end位置一个一个的移到对应的位置。

list<int> list = {1,2,3,4,5,6,7,8,9};
list<int>::iterator  it;
it = list.begin();
//如果要想访问第3个元素
it = it + 2; //错误
++(++it);  //正确,只能进行++ 或者 -- 操作 , 不能直接调位, it += 1; 都不行!

所以很显然,list容器在处理较多元素时,并不是特别方便。

二、容器特征

1.顺序容器

2.双向链表

3.动态内存分配

三、模板参数

1. T 

元素的类型,list::value_type

2. Alloc

allocator的类型,using to define the storage allocation model.   list::allocator_type

四、类型

member typedefinitionnotes
value_typeThe first template parameter (T) 
allocator_typeThe second template parameter (Alloc)defaults to: allocator<value_type>
referencevalue_type& 
const_referenceconst value_type& 
pointerallocator_traits<allocator_type>::pointerfor the default allocator: value_type*
const_pointerallocator_traits<allocator_type>::const_pointerfor the default allocator: const value_type*
iteratorbidirectional iterator to value_typeconvertible to const_iterator
const_iteratorbidirectional iterator to const value_type 
reverse_iteratorreverse_iterator<iterator> 
const_reverse_iteratorreverse_iterator<const_iterator> 
difference_typea signed integral type, identical to:
iterator_traits<iterator>::difference_type
usually the same as ptrdiff_t
size_typean unsigned integral type that can represent any non-negative value of difference_typeusually the same as size_t

五、函数 

1.构造/析构函数

1.构造函数  //constructor
2.析构函数  //destructor
3.赋值操作符   //operator = ;

2.迭代器


begin   //begin  返回一个迭代器,指向链表的第一个元素
end     //end   返回一个迭代器,指向链表末尾元素的后一个位置
 
rbegin   //rbegin  返回一个反向迭代器,指向链表“反向”起始位置,也就是最后一个元素
rend     //rend  但会一个反向迭代,指向链表“反向”末尾位置的后一个元素。如果需要反向遍历访问第一个元素,则需要 -1
 
cbegin   //返回一个const_iterator,指向链表的第一个元素
cend
 
crbegin  //返回一个const_reverse_iterator,指向链表“反向”起始位置
crend

3.容量

size             //返回size
max_size         //返回max_size
empty            //判断容器是否为空

4.获取元素

front        //访问首个元素
back         //访问末尾元素

5.修改

assign         //指定链表的内容
push_back      //从尾部插入元素
push_front     //从头部插入元素
pop_back       //从尾部弹出元素
pop_front      //从尾部弹出元素
insert         //从中间插入元素 
erase          //从中间删除元素
swap           //交换数组内容
clear          //清除链表的内容
emplace        //构建并且插入元素
emplace_front  //在头部构建并且插入元素
emplace_back   //在尾部构建并且插入元素
resize         //改变size大小

6.操作

1.splice      //将一个list当中的元素转移到另一个list当中的指定位置
    void splice (const_iterator position, list& x); 
    //将链表x转移到容器的指定位置
    void splice (const_iterator position, list& x, const_iterator i);
    //将链表x中迭代器i指向的元素插入到指定位置
    void splice (const_iterator position, list& x,
                 const_iterator first, const_iterator last);
    //将链表x中first到last 这部分元素转移到指定位置

2.remove      //删除值为value的元素
    void remove (const value_type& val);

3.remove_if   //删除符合条件的元素
    void remove_if (Predicate pred);  //括号中为条件

4.unique      //去除重复元素(包括符合条件的元素)
    void unique();
    void unique (BinaryPredicate binary_pred);  //括号中为条件

5.merge      //合并sort()过后的列表,合并出来的列表中的元素会按照顺序排列(或者按照要求排列)
    void merge (list& x);
    void merge (list& x, Compare comp);  //括号中为要求

6.sort      //将元素从小到大排列(或者按照要求排列)
    void sort();
    void sort (Compare comp);         //括号中为排列条件

7.reverse   //将列表中元素顺序颠倒

六、实例(可对每个cout << "-------------------------" << endl;下面的代码片段单独运行)

#include <iostream>
#include <list>
#include <vector> 

using namespace std;

void print(list<int> t_list)
{
	list<int>::iterator it;
	for (it = t_list.begin(); it != t_list.end(); it++)
		cout << *it << ends;
	cout << endl;
}

void print(list<double> t_list) //重载
{
	list<double>::iterator it;
	for (it = t_list.begin(); it != t_list.end(); it++)  
		cout << *it << ends;
	cout << endl;
}

bool fun_1(const int& value) { return value < 10; } //用于remove_if

struct is_odd{
	bool operator() (const int& value) { return (value % 2) == 1; }  用于remove_if
};

struct same_integral_part {
	bool operator() (const double& first, const double& second) { return (int(first) == int(second)); }
};

bool fun_2(const double& first, const double& second) { return fabs(first - second) < 5.0; } //用于unique

bool fun_3(const double& first, const double& second) { return (int(first) < int(second)); }  //用于merge

struct rsort{
	bool operator() (const int& first, const int& second) { return (first > second); }   //用与sort
};


void main()
{
	list<int> list1;
	list<int> list2 = { 1,2,3,4,5,6,7,8,9 };
	list<int> list3(5, 10);
	list<int> list4(list2.begin(), list2.end());
	list1 = list2;

	vector<list<int>> vct;
	vct.push_back(list1);
	vct.push_back(list2);
	vct.push_back(list3);
	vct.push_back(list4);

	for (auto& r : vct)
		print(r);
	/*
	cout << "list1 : ";
	print(list1);
	
	cout << "list2 : ";
	print(list2);

	cout << "list3 : ";
	print(list3);

	cout << "list4 : ";
	print(list4);
	*/
	cout << "-------------------------" << endl;
	//splice
	list<int>::iterator it1;
	it1 = list1.begin();
	cout << "list1 before change : ";
	print(list1);  // print : 10 10 10 10 10 1 2 3 4 5 6 7 8 9
	cout << "list3 before change : ";
	print(list3); // print : 
	list1.splice(it1,list3);   //移动lsit3中所有元素到list1
	cout << "list1 after change : ";
	print(list1);  // print : 10 10 10 10 10 1 2 3 4 5 6 7 8 9
	cout << "list3 after change : ";
	print(list3); // print : 
	cout << endl;


	list<int>::iterator it2;
	it2 = list2.begin();
	++it2;
	cout << "list 2 before change : ";
	print(list2);
	list2.splice(list2.begin(), list2 , it2);  // 把list2 中  it2 指向的元素 移动到 list2.begin()位置
	cout << "list 2 after change : ";
	print(list2);
	cout << endl;

	list<int>::iterator it3;
	it3 = list4.begin();
	++(++it3); // 指向第三个元素
	cout << "list 4 before change : ";
	print(list4);
	list4.splice(list4.begin(), list4, it3, list4.end());  //把list4中 it3到list4.end()这个区间的元素移动到list4.begin()位置
	cout << "list 4 after change : ";
	print(list4);
	cout << endl;

	cout << "-------------------------" << endl;
	//remove
	list<int> list5 = { 1,2,3,4,5,6,7,8,9 };
	cout << "list 5 before change : ";
	print(list5);
	list5.remove(8);  //()里面的值为list中有的value
	cout << "list 5 after change : ";
	print(list5);
	cout << endl;

	cout << "-------------------------" << endl;
	//remove_if
	list<int> list6 = { 12,45,1,798,46,123,4,5,13 };
	cout << "list 6 before change : ";
	print(list6);
	list6.remove_if(fun_1);//移除小于10的数
	cout << "list 6 the first change : ";
	print(list6);
	list6.remove_if(is_odd()); //移除奇数
	cout << "list 6 the second change : ";
	print(list6);
	cout << endl;

	cout << "-------------------------" << endl;
	//unipue
	list<double>  list7 = { 12.15,2.72,73.0,12.77,3.14,12.77,73.35,72.25,15.3,72.25 };
	cout << "list 7 before change : ";
	print(list7);
	list7.sort(); //排序
	cout << "list 7 after sort : ";
	print(list7);
	list7.unique(); //去重
	cout << "list 7 after unique() : ";
	print(list7);
	list7.unique(same_integral_part());
	cout << "list 7 after unique(same_integral_part) : ";  //去出跟前一个整数部分相同的数
	print(list7);
	list7.unique(fun_2); //去除跟前一个数相差5.0的数
	cout << "list 7 after unique(fun_2) : ";
	print(list7);
	cout << endl;
	
	
	cout << "-------------------------" << endl;
	//merge (合并)
	list<double> list8 = { 3.1, 2.2, 2.9 };
	list<double> list9 = { 3.7, 7.1, 1.4 };

	list8.sort(); //合并这一点比较重要!!!  如果不排序,则会出现错误
	list9.sort(); //合并这一点比较重要!!!  如果不排序,则会出现错误

	list8.merge(list9);
	cout << "list8 after change : ";
	print(list8);
	cout << "list9 after change : ";
	print(list9);

	list9.push_back(2.1);
	list9.push_back(3.5);
	list9.push_back(1.7);

	list9.sort(); //合并这一点比较重要!!!  如果不排序,则会出现错误

	list8.merge(list9, fun_3);  // 遍历list9  如果满足fun_3的条件,就满足条件的元素直接插入合并
	cout << "list8 after change : ";
	print(list8);
	cout << endl;

	cout << "-------------------------" << endl;
	//reverse (颠倒)
	list<int> list10;
	for (int i = 0; i < 10; i++)
		list10.push_back(i);
	cout << "list8 before reverse : ";
	print(list10);

	list10.reverse();
	cout << "list8 after reverse : ";
	print(list10);
	cout << endl;

	cout << "-------------------------" << endl;
	//sort
	list<int> list0 = { 5,1,7,9,2,4,3,1,8,4,1,32 };
	cout << "list0 before sort : ";
	print(list0);
	list0.sort();
	cout << "list0 after sort : ";
	print(list0);
	list0.sort(rsort());
	cout << "list0 after sort(rsort) : ";
	print(list0);


}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值