STL--List 常用接口简单介绍

STL--List 常用接口简单介绍:

1、底层原理:

  1. 1、list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。

  2. 2、list的底层是双向循环链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指

  3. 针指向其前一个元素和后一个元素。

  4. 3、list与forward_list非常相似:  最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高

    效。

  5. 4、与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率

    更好。

  6. 5、与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list

    的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间

  7. 开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可

  8. 能是一个重要的因素)

  9. 6、附上List文档链接:想了解更多,戳这里?

2、模块介绍:

         list中的接口比较多,以下为list中一些常见的重要接口:

         1>构造:

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

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

  • begin() + end()----(正向迭代器)---返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器
  • rbegin() + rend()----(反向迭代器)---返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的 reverse_iterator,即begin位置

       3、list  capacity

  • empty()----------------检测list是否为空,是返回true,否返回false
  • size()------------------返回list中有效节点的个数

      4、list element access

  • front()------------------返回list的第一个节点中值的引用
  • back()------------------返回list的最后一个节点中值的引用

      5、list  modifiers

  • 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中的有效元素

      6、特别注意:⚠️List中迭代器失效问题

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

        具体看代码。

3、代码实现:

//STL_List  list的常用接口简单使用
#include<iostream>
using namespace std;

//list:带头节点的双向循环链表

#include<list>
#include<vector>

//list构造

void TestList1()
{
	list<int> L1;    //构造空的L1
	list<int> L2(10,5);    //L2中放10个值为5的元素
	vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	list<int> L3(v.begin(), v.end());            //区间构造    vector 提供构造区间。
	//[begin(),end()),左闭右开
	list<int> L4(arr, arr + sizeof(arr) / sizeof(arr[0]));      //区间构造    数组提供构造区间。
	list<int> L5(L4);    //拷贝构造

	cout << L1.size() << endl;

	//迭代器访问L2
	//list<int>::iterator it = L2.begin();           //C++98  提供的办法
	auto  it = L2.begin();          //C++11 提供的办法
	while (it != L2.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	//范围for循环遍历L3     //C++11
	for (auto e : L3)
	{
		cout << e << " ";
	}
	cout << endl;

	cout << L4.front() << endl;
	cout << L4.back() << endl;

	//反向迭代器遍历L5
	auto rit = L5.rbegin();
	while (rit != L5.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
}

//List增删改查

void TestList2()
{
	list<int> L;
	L.push_back(1);            //尾插   插入五个元素
	L.push_back(2);
	L.push_back(3);
	L.push_back(4);
	L.push_back(5);

	cout << L.size() << endl;

	L.push_front(0);            //头插
	cout << L.front() << endl;

	L.pop_back();              //尾删
	cout << L.back() << endl;

	L.pop_front();               //头删
	cout << L.front() << endl;

	//1  2   3   4
	//list<int>::iterator it = L.begin();    //C++98
	auto it = L.begin();     //C++11  定义迭代器

	it = find(L.begin(), L.end(), 2);     //find()方法在区间内找第一个值为2的元素,返回值为该元素的迭代器
	if (it != L.end())    //判断条件保证L不为空
	{
		L.insert(it, 9);            //insert方法在it位置之前插入9
	}

	L.erase(it);            //删除it位置元素,要注意:此时it的含义--〉it指向第一次找到的值为2的元素,因此这里会删除之前找到的元素2

	cout << L.size() << endl;

	//IsOdd(int data);   操作同上
}
	
//remove()  ,  remove_if()

// 判断偶数操作
bool IsEven(int data)
{
	if (0 == data % 2)
		return true;
	return false;
}
//判断奇数操作
bool IsOdd(int data)
{
	if (0 == data % 2)
		return true;
	return false;
}

void TestList3()
{
	list<int> L{ 1, 2, 3, 2, 2, 4, 2 };
	for (auto e : L)
	{
		cout << e << " ";
	}
	cout << endl;

	//删除所有的2
	L.remove(2);            //remove()方法为删除所有和所传值相同的元素
	//1 3 4
	cout << L.size() << endl;

    //删除L中所有的偶数
	L.remove_if(IsEven);     //remove_if()方法为删除所有符合条件的元素,函数参数即为条件
	//1 3
	cout << L.size() << endl;

	//L.remove_if(IsOdd);   //删除L中所有的奇数
}

//unique()

void TestList4()
{
	list<int> L{ 1, 2, 3, 4, 9, 2, 2, 4, 2 };
	L.sort();      //排序
	for (auto e : L)
	{
		cout << e << " ";
	}
	cout << endl;

	//unique():去重,删掉重复的元素
	//使用unique()前提是保证链表是有序的
    L.unique();     
	auto it = L.begin();
	while (it != L.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

//迭代器失效问题
//list中迭代器失效----〉迭代器指向的节点不存在
void TestList5()
{
	list<int> L{ 1, 2, 3, 4 };
	//list<int>::iterator it = L.begin();    //C++98
	auto it = L.begin();    //C++11

	L.erase(it);   
	//it迭代器失效,erase之后,it所指向的节点已经被删除了
    //解决办法:重新给it赋值
	it = L.begin();
	while (it != L.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}
int main()
{
	//TestList1();           //list构造
	//TestList2();           //List增删改查
	//TestList3();           //remove()  ,  remove_if()
	//TestList4();           //unique()
	TestList5();           //迭代器失效问题

	return 0;
}
发布了83 篇原创文章 · 获赞 26 · 访问量 8706

猜你喜欢

转载自blog.csdn.net/lexiaoyao_0000/article/details/102534432