C++ STL list 容器 一一(包含list所有内容)

list容器

list是序列容器,它允许在序列的任何地方进行常量时间插入和删除操作,并在两个方向进行迭代。
list容器底层实现为双链表;双链表可以将它们包含的每个元素存储在不同且不相关的存储位置。顺序通过与链接的每个元素之间的关联保持在内部,链接指向前面的元素,链接指向后面的元素。
list与forward_list非常相似:主要的区别在于forward_list对象是单链列表,因此只能向前迭代,以换取更小、更高效。与其他基本标准序列容器(array, vector , deque)相比,list通常在插入、提取和移动元素方面表现得更好,这些元素在容器中的任何位置都已经获得了迭代器,因此,在大量使用这些元素的算法中,比如排序算法,列表的性能也更好。
与其他序列容器相比,list和forward_lists的主要缺点是它们不能根据位置直接访问元素;例如,要访问列表中的第6个元素,必须从一个已知的位置(如开始或结束)迭代到该位置,这将花费这些元素之间的线性时间。

list底层类模板

template < class T, class Alloc = allocator<T> > class list;

T
元素的类型。
别名为成员类型list::value_type。
Alloc
用于定义存储分配模型的分配器对象的类型。默认情况下,使用的是分配器类模板,它定义了最简单的内存分配模型,并且是独立于值的。
别名为成员类型list::allocator_type。

list 迭代器

1、begin:返回迭代器到开始(公共成员函数)
2、end:返回迭代器末尾(公共成员函数)
3、rbegin:返回反向迭代器到反向开始(公共成员函数)
4、rend:返回反向迭代器到反向端(公共成员函数)
5、cbegin:将const_iterator返回到开始(公共成员函数)
6、cend:返回const_iterator返回到末尾(公共成员函数)
7、crbegin:返回const_reverse_iterator到反向开始(公共成员函数)
8、crend:返回const_reverse_iterator到反向末尾(公共成员函数)

begin/end

1、begin返回指向列表容器中第一个元素的迭代器。公共成员函数有两个:
iterator begin();
2、const_iterator begin() const;
3、end返回一个迭代器,该迭代器引用列表容器中的结束后元素。公共成员函数有两个:
4、iterator end();
5、const_iterator end() const;

直接上代码吧,这样更直观些…

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

int main (int argc, char **argv)
{  

	int table[] = {1,3,8,4,3,6};
	list<int> mylist(table,table+6);

	for (list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout <<"mylist: " << *it<<endl;
	}

  	return 0;
}

输出结果:
在这里插入图片描述

rbegin/rend

1、rbegin 返回指向容器中最后一个元素的反向迭代器。序列容器的反向开头的反向迭代器。公共成员函数也有两个迭代器类型:
2、reverse_iterator rbegin();
3、const_reverse_iterator rbegin() const;

4、rend 返回一个反向迭代器,该迭代器指向列表容器中第一个元素之前的理论元素。公共成员函数也有两个迭代器类型:
5、reverse_iterator rend();
6、const_reverse_iterator rend() const;

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

int main (int argc, char **argv)
{  
	list<int> mylist={1,2,3,4,5};

	for (list<int>::reverse_iterator it = mylist.rbegin(); it != mylist.rend(); ++it)
	{
		cout <<" " << *it;
	}
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述

cbegin/cend

1、cbegin在c++11中才引入进来。返回指向容器中第一个元素的const_iterator。成员迭代器有一个:
const_iterator cbegin() const noexcept;

2、cend也是一样c++11才有的,返回指向容器中结束后元素的const_iterator。成员迭代器也只有一个类型:
const_iterator cend() const noexcept;
#include <iostream>
#include <list>
using namespace std;

int main (int argc, char **argv)
{  
	list<int> mylist={1,2,3,4,5};

	// auto = list<int>::const_iterator
	for (list<int>::const_iterator  it = mylist.cbegin(); it != mylist.cend(); ++it)
	{
		cout <<" " << *it;
	}
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述
crbegin/crend

1、crbegin  c++11才支持,返回指向容器中最后一个元素的const_reverse_iterator类型。
成员函数只有一个:
const_reverse_iterator crbegin() const noexcept;

2、crend c++11才支持,返回指向容器中第一个元素之前的理论元素的const_reverse_iterator类型,迭代器有一个类型:
const_reverse_iterator crend() const noexcept;
#include <iostream>
#include <list>
using namespace std;

int main (int argc, char **argv)
{  
	list<int> mylist={1,2,3,4,5};

	// auto = list<int>::const_reverse_iterator 
	for (list<int>::const_reverse_iterator   it = mylist.crbegin(); it != mylist.crend(); ++it)
	{
		cout <<" " << *it;
	}
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述

list容量

1、empty:测试容器是否为空(公共成员函数)
2、size:返回大小(公共成员函数)
3、max_size:返回最大大小(公共成员函数)

empty

返回列表容器是否为空,成员函数为:

bool empty() const;
#include <iostream>
#include <list>
using namespace std;

int main (int argc, char **argv)
{  
	int sum = 0;
	list<int> mylist;

	for (int i = 1; i <= 10; ++i)
	{
		mylist.push_back(i);
	}

	for (auto it = mylist.begin(); it != mylist.end() && !mylist.empty(); ++it)
	{
		sum += *it;
	}
	cout <<" sum: " << sum;
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述
size

size 返回列表容器中的元素数量。成员函数为:

size_type size() const;
#include <iostream>
#include <list>
using namespace std;

int main (int argc, char **argv)
{  
	list<int> mylist;

	for (int i = 1; i <= 10; ++i)
	{
		mylist.push_back(i);
	}
	cout <<" size: " << mylist.size();
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述
max_size

max_size 返回列表容器可以容纳的元素的最大数量。成员函数为:

size_type max_size() const;
#include <iostream>
#include <list>
using namespace std;

int main (int argc, char **argv)
{  
	list<int> mylist;

	for (int i = 1; i <= 10; ++i)
	{
		mylist.push_back(i);
	}
	cout <<" max_size: " << mylist.max_size();
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述
list元素访问

front:访问第一个元素(公共成员函数)
back:访问最后一个元素(公共成员函数)

front/back

1、front 返回对列表容器中第一个元素的引用。front 访问元素有两个版本:
reference front();
const_reference front() const;

2、back 返回对列表容器中最后一个元素的引用。back也有两个版本:
reference back();
const_reference back() const;
#include <iostream>
#include <list>
using namespace std;

int main (int argc, char **argv)
{  
	list<int> mylist={12,4};

	mylist.front() -= mylist.back();

	cout <<" mylist.front() : " << mylist.front();
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述

#include <iostream>
#include <list>
using namespace std;
int main (int argc, char **argv)
{  
	list<int> mylist = {10};

	while (mylist.back() != 0)
	{
		mylist.push_back(mylist.back()-1);
	}

	for (auto it = mylist.begin(); it != mylist.end() ; ++it)
	{
		cout <<" "<<*it;
	}
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述
list Modifiers

1、emplace_front:在开始时构造和插入元素(公共成员函数)
2、push_front:在开始时插入元素(公共成员函数)
3、pop_front:删除第一个元素(公共成员函数)
4、emplace_back:在末尾构造和插入元素(公共成员函数)
5、push_back:在末尾添加元素(公共成员函数)
6、pop_back:删除最后一个元素(公共成员函数)
7、emplace:构造和插入元素(公共成员函数)
8、insert:插入元素(公共成员函数)
9、erase:删除元素(公共成员函数)
10、swap:交换内容(公共成员函数)
11、resize:更改大小(公共成员功能)
12、clear:清除内容(公众成员功能)

emplace_front

emplace_front 在开始时构造和插入元素。
template <class… Args>
void emplace_front (Args&&… args);


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

int main (int argc, char **argv)
{  
	list<pair<int,char>> mylist;
	mylist.emplace_front(10,'a');
	mylist.emplace_front(20,'b');
	mylist.emplace_front(30,'c');

	for (auto it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout <<"("<<it->first << "," << it->second <<") ";
	}
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述

push_front

push_front 在开始时插入元素(公共成员函数),公有成员函数有一个:
void push_front (const value_type& val);
在列表的开头插入一个新元素,就在它当前的第一个元素之前。val的内容被复制(或移动)到插入的元素。
#include <iostream>
#include <list>
using namespace std;

int main (int argc, char **argv)
{  
	
	list <int> mylist(2,100);//mylist有2个元素,每个的值都是100

	mylist.push_front(200);
	mylist.push_front(300);

	for (auto it = mylist.begin(); it != mylist.end(); ++it)
	{
		 cout <<" " <<*it;
	}
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述

pop_front

pop_front 删除第一个元素。公有成员只有一个:

void pop_front();
#include <iostream>
#include <list>
using namespace std;

int main (int argc, char **argv)
{  
	
	list <int> mylist = {100,200,300};

	while(!mylist.empty())
	{
		cout <<mylist.front()<<" ";
		mylist.pop_front();
	}
	cout << endl;
	cout <<"size: "<<mylist.size();
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述
emplace_back

emplace_back 构造并在末尾插入元素。
template <class... Args>
void emplace_back (Args&&... args);
在列表末尾插入一个新元素,就在它当前的最后一个元素之后。这个新元素是使用args作为构造参数来构造的。
#include <iostream>
#include <list>
using namespace std;

int main (int argc, char **argv)
{  
	
	list<pair<int,char>>mylist;
	mylist.emplace_back(100,'a');
	mylist.emplace_back(200,'b');
	mylist.emplace_back(300,'c');

	for (auto it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout <<"("<<it->first<<","<<it->second<<")";
	}
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述
push_back/pop_back

push_back 在末尾添加元素。
void push_back (const value_type& val);
在列表容器的最后一个元素之后,在列表容器的末尾添加一个新元素。val的内容被复制(或移动)到新元素。

pop_back 删除最后一个元素
void pop_back();
删除列表容器中的最后一个元素,有效地将容器大小减少了。
#include <iostream>
#include <list>
using namespace std;

int main (int argc, char **argv)
{  
	int sum = 0;
	list<int> mylist;
	mylist.push_back(1);
	mylist.push_back(2);
	mylist.push_back(3);
	mylist.push_back(4);
	mylist.push_back(5);
	mylist.push_back(6);

	while (!mylist.empty())
	{
		sum += mylist.back();
		mylist.pop_back();
	}

	// for (auto it = mylist.begin(); it != mylist.end() && !mylist.empty(); ++it)
	// {
	// 	sum += *it;		
	// }

	cout <<" sum: "<<sum;
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述

emplace

emplace 构造和插入元素。公有成员函数如下:
template <class... Args>
iterator emplace (const_iterator position, Args&&... args);
通过在位置插入一个新元素来扩展容器。这个新元素是使用args作为构造参数来构造的。
#include <iostream>
#include <list>
using namespace std;

int main (int argc, char **argv)
{  
	int sum = 0;
	list<pair<int,char>> mylist;
	mylist.emplace(mylist.begin(),10,'a');
	mylist.emplace(mylist.begin(),20,'b');
	mylist.emplace(mylist.begin(),30,'c');

	// auto = list<int>::iterator 
	for (auto it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout <<" ("<<it->first<<","<<it->second<<") ";
	}

	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述

insert

insert 插入元素。insert底层版本支持三种:
(1)iterator insert (iterator position, const value_type& val);
(2)void insert (iterator position, size_type n, const value_type& val);
(3)template <class InputIterator>
    void insert (iterator position, InputIterator first, InputIterator last);
通过在指定位置的元素之前插入新元素来扩展容器。这实际上增加了插入元素的数量,从而增加了列表的大小。与其他标准序列容器不同,list和forward_list对象是专门设计用来在任何位置(甚至在序列中间)高效插入和删除元素的。
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;

int main (int argc, char **argv)
{  

	list<int>mylist = {1,2,3,4,5};
	mylist.push_front(10); //添加到整数的开头
	mylist.push_back(12); //添加到整数的结尾

	cout << "number: ";
	for(int n: mylist)
	{
		cout <<" " << n;
	}
	cout << endl;

	//搜索在3前的值,然后插入进去
	
	auto it = find(mylist.begin(),mylist.end(),3);
	if (it != mylist.end())
	{
		mylist.insert(it,66);
	}
	cout <<" in the end: ";
	//迭代遍历
	for(int n: mylist)
	{
		cout <<" " << n;
	}
	cout <<endl;
  	return 0;
}

输出结果:
在这里插入图片描述
erase

erase 删除元素。

1、iterator erase (iterator position);
2、iterator erase (iterator first, iterator last);

从列表容器中删除单个元素(位置)或元素范围([first,last])。这有效地减少了容器的大小,减少了被删除的元素的数量。

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

int main (int argc, char **argv)
{  

	list<int>mylist = {0,1,2,3,4,5,6};


	for (int n: mylist)
	{
		cout <<n ;
	}
	cout << endl;

	mylist.erase(mylist.begin()); //删除第一个元素
	//迭代遍历
	for (auto &n: mylist)
	{
		cout <<n ;
	}
	cout << endl;

	list<int>::iterator range_begin = mylist.begin();
	list<int>::iterator range_end = mylist.end();
	advance(range_begin,2);
	advance(range_end,5);

	mylist.erase(range_begin,range_end);

	for (auto it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout <<*it;
	}
	cout <<endl;

  	return 0;
}

输出结果:
在这里插入图片描述

swap

swap 交换内容
void swap (list& x);
通过x的内容交换容器的内容,x是另一个相同类型的列表。大小可能不同。
在调用这个成员函数之后,这个容器中的元素是调用之前x中的元素,而x的元素是这个容器中的元素。所有迭代器、引用和指针仍然对交换的对象有效。

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

int main (int argc, char **argv)
{  

	list<int>listA(3,100);
	list<int>listB(5,200);

	listA.swap(listB);
	cout <<"listA:";
	for (auto it = listA.begin(); it != listA.end(); ++it)
	{
		cout <<" "<<*it;
	}
	cout << endl;
	cout <<"listB:";
	for (auto it = listB.begin(); it != listB.end(); ++it)
	{
		cout<<" " <<*it;
	}
	cout << endl;
  	return 0;
}

输出结果:
在这里插入图片描述
clear

clear清除内容;
void clear();
从列表容器中删除所有元素(已销毁的元素),并将容器的大小保留为0。

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

int main (int argc, char **argv)
{  

	list<int>mylist(3,100); //mylist有三个值,每个值都是100
	

	mylist.clear();
	mylist.push_back(200);
	mylist.push_back(300);

	for (auto it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout<<" " <<*it;
	}
	cout << endl;
  	return 0;
}

输出结果:
在这里插入图片描述

list常见算法函数

1、splice:将元素从一个列表转移到另一个列表(公共成员函数)
2、remove:删除具有特定值的元素(公共成员函数)
3、remove_if:删除满足条件的元素(公共成员函数模板)
4、unique:删除重复值(公共成员函数)
5、merge:合并排序列表(公共成员函数)
6、sort:在容器中对元素排序(公共成员函数)
7、reverse:反转元素顺序(公共成员函数)

splice


splice 将元素从一个列表转移到另一个列表,底层支持版本有三个:
(1)	void splice (iterator position, list& x);
(2)	void splice (iterator position, list& x, iterator i);
(3)	void splice (iterator position, list& x, iterator first, iterator last);

将元素从x转移到容器中,并将其插入位置。这可以有效地将这些元素插入容器并从x中删除它们,从而改变两个容器的大小。该作业不涉及任何元件的建造或销毁。不管x是lvalue还是rvalue,也不管value_type是否支持移动构造,它们都被传输。
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;

int main (int argc, char **argv)
{  

	list<int>listA = {1,2,3,4,5};
	list<int>listB = {10,20,30,40,50};

	auto it = listA.begin();
	advance(it,3);

	listA.splice(it,listB);

	//遍历
	cout <<"listA:";
	for(int n:listA)
	{
		cout <<" "<<n;
	}
	cout <<endl;
	cout <<"listB:";
	for(int n:listB)
	{
		cout <<" "<<n;
	}
	cout <<endl;

	listB.splice(listB.begin(),listA,it,listA.end());
	//遍历
	cout <<"listA:";
	for(int n:listA)
	{
		cout <<" "<<n;
	}
	cout <<endl;
	cout <<"listB:";
	for(int n:listB)
	{
		cout <<" "<<n;
	}
	cout <<endl;

  	return 0;
}

输出结果:
在这里插入图片描述
remove

remove 删除具有特定值的元素。
void remove (const value_type& val);
从容器中删除所有与val相比较的元素。这将调用这些对象的析构函数,并通过删除的元素数量减少容器的大小。

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

int main (int argc, char **argv)
{  

	list<int>mylist = {10,5,56,23,18};

	mylist.remove(5);

	for (auto it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout <<" "<<*it;
	}
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述

remove_if

1、remove_if 移除满足条件的元素;
2template <class Predicate>
3void remove_if (Predicate pred);
从容器中删除Predicate pred返回true的所有元素。这将调用这些对象的析构函数,并通过删除的元素数量减少容器大小。
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;

int data_less(const int &value)
{

	return (value <= 10);
}

int main (int argc, char **argv)
{  

	list<int>mylist = {10,5,56,23,18};

	mylist.remove_if(data_less);

	for (auto it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout <<" "<<*it;
	}
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述
unique

unique 删除重复的值;支持两个版本;
(1)	void unique();
(2)	template <class BinaryPredicate>
  void unique (BinaryPredicate binary_pred);
 没有参数(1)的版本从容器中每个连续的相等元素组中删除除第一个元素外的所有元素。
第二个版本(2)将确定元素“惟一性”的特定比较函数作为参数。事实上,任何行为都可以实现(不仅相等的比较),但请注意,函数将调用binary_pred 对所有元素(我是一个元素的迭代器,从第二个开始)和删除我从列表中如果谓词返回true
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;

int main (int argc, char **argv)
{  

	list <int> mylist = {1,2,3,3,3,3,5,1,2,2,4};
	cout <<"Before the change:";
	for(int n : mylist)
	{
		cout <<" "<<n;
	}
	cout <<endl;

	mylist.unique();
	cout <<"After the change:";
	for(int n : mylist)
	{
		cout <<" "<<n;
	}
	cout << endl;


  	return 0;
}

输出结果:
在这里插入图片描述

merge

merge 合并排序的列表。
(1)	 void merge (list& x);
(2)	template <class Compare>
  void merge (list& x, Compare comp);
通过将x在各自的有序位置上的所有元素转移到容器中,将x合并到列表中(两个容器都应该已经被有序)
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;

int main (int argc, char **argv)
{  

	list <int> listA = {2,7,8,3,9,4};
	list <int> listB = {6,8,9,1,0,5};
	listA.sort();
	listB.sort();

	cout <<"listA:";
	for(int n : listA)
	{
		cout <<" "<<n;
	}
	cout << endl;

	cout <<"listB:";
	for(int n : listB)
	{
		cout <<" "<<n;
	}
	cout << endl;
	
	listA.merge(listB);

	cout <<"merge: "; //合并两个已排序链表为一个
	for (auto &n : listA)
	{
		cout <<" "<< n;
	}
	cout << endl;
	//去除连续重复数据
	listA.unique();
	cout <<"unique: ";
	for (auto it = listA.begin(); it != listA.end(); ++it)
	{
		cout <<" "<<*it;
	}
	cout << endl;

  	return 0;
}

输出结果:
在这里插入图片描述

sort

sort 容器中的排序元素。

(1)	
  void sort();
(2)	
template <class Compare>
  void sort (Compare comp);
排序列表中的元素,更改它们在容器中的位置。
#include <iostream>
#include <list>
#include <functional>
using namespace std;

int main (int argc, char **argv)
{  
	list <int> mylist = {8,7,5,9,0,1,3,2,6,4};

	cout << "before:";
	for (int n : mylist)
	{
		cout <<" "<<n;
	}
	cout << endl;

	mylist.sort();

	cout <<"sort after:";

	for (int n : mylist)
	{
		cout <<" "<< n;
	}
	cout << endl;

	mylist.sort(greater<int>());
	cout << "greater:";
	for (int n : mylist)
	{
		cout <<" "<< n;
	}
	cout << endl;
  	return 0;
}

输出结果:
在这里插入图片描述

reverse


reverse 颠倒元素的顺序。
void reverse();
反转列表容器中元素的顺序。
#include <iostream>
#include <list>
#include <functional>
using namespace std;

int main (int argc, char **argv)
{  
	list <int> mylist = {8,7,5,9,0,1,3,2,6,4};

	cout << "before:";
	for (int n : mylist)
	{
		cout <<" "<<n;
	}
	cout << endl;

	mylist.sort();

	cout <<"sort after:";

	for (int n : mylist)
	{
		cout <<" "<< n;
	}
	cout << endl;

	mylist.reverse();
	cout << "reverse:";
	for (auto it = mylist.begin(); it != mylist.end(); ++it)
	{
		cout <<" "<<*it;
	}
	cout << endl;
  	return 0;
}

输出结果:
在这里插入图片描述

在这里插入图片描述

扫二维码关注微信公众号,获取技术干货

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值