list

1.list

1.1list概述

list是c++中stl中自带的容器,list是由双向链表来实现的,每个节点存储1个元素。list支持前后两种移动方向。

头文件:

#include <list>

优势: 任何位置执行插入和删除动作都非常快

list与vector的区别:

list不支持随机存取;

在list的任何位置执行插入和移除都非常快.插入和删除动作不影响指向其它元素的指针,引用,迭代器,不会造成失效;

list不支持随机存取,不提供下标操作符和at()函数;

list没有提供容量,空间重新分配等操作函数,每个元素都有自己的内存;

list也提供了特殊成员函数,专门用于移动元素.

1.2 list的使用

1.2.1 list的构造

list中的接口比较多,此处类似,只需要掌握如何正确的使用,然后再去深入研究背后的原理,已达到可扩展的能力。以下为list中一些常见的重要接口。

|-----------------------------------------------------------------------------------------|----------------------------|
| 构造函数((constructor)) | 接口说明 |
| list (size_type n, const value_type& val = value_type()) | 构造的list中包含n个值为val的元素 |
| list() | 构造空的list |
| list (const list& x) | 拷贝构造函数 |
| list (InputIterator first, InputIterator last) | 用[first, last)区间中的元素构造list |

list<A> listname;
list<A> listname(size);
list<A> listname(size,value);
list<A> listname(elselist);
list<A> listname(first, last);

1.2.2迭代器

此处,大家可暂时将迭代器理解成一个指针,该指针指向list中的某个节点。

|----------------------|-------------------------------------------------------------------------|
| 构造函数( (constructor)) | 接口说明 |
| begin + end | 返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器 |
| rbegin +end | 返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的reverse_iterator,即begin位置 |

【注意】

  1. begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动
  2. rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动

函数声明 接口说明

|-------------------------------------------------------------------|------------------------------|
| 构造函数( (constructor)) | 接口说明 |
| empty | 检测list是否为空,是返回true,否则返回false |
| size | 返回list中有效节点的个数 |

1.2.3 list capacity

|-------------------------------------------------------------------|--------------------|
| 构造函数( (constructor)) | 接口说明 |
| front | 返回list的第一个节点中值的引用 |
| back | 返回list的最后一个节点中值的引用 |

|----------------------------------------------------------------------------------|------------------------------|
| push_front | 在list首元素前插入值为val的元素 |
| pop_front | 删除list中第一个元素 |
| push_back | 在list尾部插入值为val的元素 |
| pop_back | 删除list中最后一个元素 |
| insert | 在list position 位置中插入值为val的元素 |
| erase | 删除list position位置的元素 |
| swap | 交换两个list中的元素 |
| clear | 清空list中的有效元素 |

2. list的迭代器失效

前面说过,此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

void TestListIterator1()
{
 int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; list<int> l(array, array+sizeof(array)/sizeof(array[0]));
 auto it = l.begin(); while (it != l.end()) {
 // erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给
其赋值
 l.erase(it); 
 ++it;
 }
}
// 改正
void TestListIterator()
{
 int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; list<int> l(array, array+sizeof(array)/sizeof(array[0]));
 auto it = l.begin(); while (it != l.end()) { l.erase(it++); // it = l.erase(it); }
}

使用代码展示:

#pragma warning(disable:4786)
#include <iostream>
#include <list>
#include <algorithm>
#include <string>
//#include <iomanip.h>

using namespace std;

template <class T>void print(const T& Ele)
{
	cout<<" "<<Ele<<";"<<endl;
}

// 格式化输出
void Print_D(double& Ele)
{
	cout.width(5);			// 宽度5
	cout.precision(1);		// 保留1位小数
	cout<<std::fixed<<Ele<<", ";
}
void Print_I(int& Ele)
{
	cout<<Ele<<",  ";
}

void main()
{
	//上定义双向队列
	list<string>mylist_string;
	list<double>mylist_double(6);
	
	//---------初始化mylist_string
	mylist_string.push_front("1:  Jack");
	mylist_string.push_front("2:  Tom");
	mylist_string.push_front("3:  Mike");

	//---------初始化mylist_double
	mylist_double.push_front(10.0);
	mylist_double.push_front(20.0);
	mylist_double.push_front(30.0);
	mylist_double.push_front(40.0);
	mylist_double.push_front(50.0);

	//下述是三种容器定义形式
	list<int> mylist_int(6,0);			// 6个0:0 0 0 0 0 0
	list<double>mylist_double2(6,0.0);	// 6个0.0:0.0 0.0 0.0 0.0 0.0 0.0
	list<int>elselist(mylist_int);		// 以其它双向队列初始化
	list<double>Iterlist(mylist_double.begin(),mylist_double.end());	// 以其他队列初始化

	//----输出各个容器中的元素
	cout<<"打印 mylist_string:"<<endl;
	list<string>::iterator iter_String;	// 迭代器
	for(iter_String=mylist_string.begin();iter_String!=mylist_string.end();iter_String++)
	{
		string temp=*iter_String;
		print(temp);
	}
	cout<<"打印 mylist_double:"<<endl;
	for_each(mylist_double.begin(),mylist_double.end(),Print_D);
	cout<<endl;


	cout<<"打印 mylist_double2:"<<endl;
	for_each(mylist_double2.begin(),mylist_double2.end(),Print_D);
	cout<<endl;

	cout<<"打印 Iterlist:"<<endl;
	for_each(Iterlist.begin(),Iterlist.end(),Print_D);
	cout<<endl;

	cout<<"打印 mylist_int:"<<endl;
	for_each(mylist_int.begin(),mylist_int.end(),Print_I);
	cout<<endl;

	cout<<"打印 elselist:"<<endl;
 	for_each(elselist.begin(),elselist.end(),Print_I);
	cout<<endl;

	//各容器的容量
	int size=mylist_string.size();
	int maxsize=mylist_string.size();
	mylist_string.resize(5);

	size=mylist_double.size();
	maxsize=mylist_double.max_size();
	mylist_double.resize(5);

	size=mylist_double2.size();
	maxsize=mylist_double2.max_size();
	mylist_double2.resize(5);

	size=Iterlist.size();
	maxsize=Iterlist.max_size();
	Iterlist.resize(5);

	size=mylist_int.size();
	maxsize=mylist_int.max_size();
	mylist_int.resize(5);

	size=elselist.size();
	maxsize=elselist.max_size();
	elselist.resize(5);

	//----再次输出各个容器中的元素
	cout<<"打印 mylist_string:"<<endl;
			     for(iter_String=mylist_string.begin();iter_String!=mylist_string.end();iter_String++)
	{
		string temp=*iter_String;
		print(temp);
	}
	cout<<"打印 mylist_double:"<<endl;
	for_each(mylist_double.begin(),mylist_double.end(),Print_D);
	cout<<endl;

	cout<<"打印 mylist_double2:"<<endl;
	for_each(mylist_double2.begin(),mylist_double2.end(),Print_D);
	cout<<endl;

	cout<<"打印 Iterlist:"<<endl;
	for_each(Iterlist.begin(),Iterlist.end(),Print_D);
	cout<<endl;

	cout<<"打印 mylist_int:"<<endl;
	for_each(mylist_int.begin(),mylist_int.end(),Print_I);
	cout<<endl;

	cout<<"打印 elselist:"<<endl;
 	for_each(elselist.begin(),elselist.end(),Print_I);
	cout<<endl;


	//使用迭代器相关的函数
	list<double>::iterator Iter_D;
	list<double>::reverse_iterator Iter_rD;
	cout<<"打印 mylist_double 所有元素:"<<endl;
	for_each(mylist_double.begin(),mylist_double.end(),Print_D);
	cout<<endl;

	double tmp=0.0;
	Iter_D=mylist_double.begin();
	tmp=*Iter_D;
	cout<<"打印 mylist_double 的 begin:"<<endl;
	cout<<tmp<<endl;

	Iter_rD=mylist_double.rbegin();
	tmp=*Iter_rD;
	cout<<"\r\n打印 mylist_double 的 rbegin:"<<endl;
	cout<<tmp<<endl;

 	Iter_D=mylist_double.end();
	Iter_D--; // 必须--,end为指向最后一个元素所在位置后一个位置
	tmp=*Iter_D;
	cout<<"打印 mylist_double 的 end:"<<endl;
	cout<<tmp<<endl;

	Iter_rD=mylist_double.rend();
	Iter_rD--; // 必须--,rend为指向第一个元素所在位置前一个位置
	tmp=*Iter_rD;
	cout<<"打印 mylist_double 的 rend:"<<endl;
	cout<<tmp<<endl;

 	tmp=mylist_double.front();
	cout<<"打印 mylist_double 的 front:"<<endl;
	cout<<tmp<<endl; //
	//cout<<mylist_double.front()<<endl;

 	tmp=mylist_double.back();
	cout<<"打印 mylist_double 的 back:"<<endl;
	cout<<tmp<<endl; 
}
相关推荐
2401_858286113 小时前
115.【C语言】数据结构之排序(希尔排序)
c语言·开发语言·数据结构·算法·排序算法
猫猫的小茶馆3 小时前
【数据结构】数据结构整体大纲
linux·数据结构·算法·ubuntu·嵌入式软件
2401_858286114 小时前
109.【C语言】数据结构之求二叉树的高度
c语言·开发语言·数据结构·算法
huapiaoy4 小时前
数据结构---Map&Set
数据结构
南宫生4 小时前
力扣-数据结构-1【算法学习day.72】
java·数据结构·学习·算法·leetcode
yuanbenshidiaos4 小时前
数据结构---------二叉树前序遍历中序遍历后序遍历
数据结构
^南波万^4 小时前
数据结构--排序
数据结构
yuanbenshidiaos5 小时前
数据结构----链表头插中插尾插
网络·数据结构·链表
逊嘘5 小时前
【Java数据结构】LinkedList
java·开发语言·数据结构
Yan.love8 小时前
开发场景中Java 集合的最佳选择
java·数据结构·链表