0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

c++之list容器

嵌入式技术 来源:嵌入式技术 作者:嵌入式技术 2023-07-15 08:53 次阅读

1.list容器简介

list是序列容器,允许在序列中的任何位置执行固定O(1)时间复杂度的插入和删除操作,并在两个方向进行迭代。list容器是一个双向循环链表。

  • list容器与vector容器区别:

list中空间是随机的,通过指向域保存下一个成员地址;vector容器空间是连续的;

list容器数据插入和删除方便,能合理的利用空间;vector容器则是没法实时分配资源;

wKgaomSxP96ASzZmAAfWkse885c857.png

2.list容器构造函数

list容器构造函数:
	list< T > p;//默认构造
	list(begin,end);//区间赋值
	list(int num,elem);//num个elem值
	list(const list &p);//拷贝构造
	取头数据:front()
	取尾数据:back();
	互换成员swap();

使用示例:

#include < iostream >
using namespace std;
#include < list >
/*遍历*/
void PrintList(const list< int >& p, int flag)
{
	if (flag == 1)//正向遍历
	{
		cout < < "正向遍历:" < < endl;
		for (list< int >::const_iterator ptr = p.begin(); ptr != p.end(); ptr++)
		{
			cout < < *ptr < < " ";
		}
	}
	else //逆向遍历
	{
		cout < < "逆向遍历:" < < endl;
		for (list< int >::const_reverse_iterator ptr = p.rbegin(); ptr != p.rend(); ptr++)
		{
			cout < < *ptr < < " ";
		}
	}
	cout < < endl;
}
void test()
{
	list< int > lst;//默认构造
	//尾插法
	lst.push_back(100);
	lst.push_back(200);
	//头插法
	lst.push_front(300);
	lst.push_front(400);
	PrintList(lst, 1);
	PrintList(lst, 0);
	list< int > lst2(lst.begin(), lst.end());//区间赋值
	cout < < "lst2第一个成员:" < < lst2.front() < < endl;
	cout < < "lst2最后一个成员:" < < lst2.back() < < endl;
	cout < < "tlst3" < < endl;
	list< int > lst3(3, 666);//3个666
	PrintList(lst3, 1);
	list< int > lst4(lst2);//拷贝构造
}
int main()
{
	test();
	system("pause");
}
wKgaomSxQFCAZY4_AAPWBdLGxEs306.png

3.list容器赋值与互换成员

list容器赋值:
	重载运算符=: list& operator=(const list &p);
	siggn(int num,elem);//num个elem
	siggn(begin,end);//区间赋值
互换:
	swap(list &p);

使用示例:

#include < iostream >
using namespace std;
#include < list >
void PrintList(const list< int >& p)
{
	for (list< int >::const_iterator ptr = p.begin(); ptr != p.end(); ptr++)
	{
		cout < < *ptr < < " ";
	}
	cout < < endl;
}
void test()
{
	list< int > lst;
	for (int i = 10; i <= 30; i += 10)
	{
		lst.push_back(i);
	}
	list< int > lst2 = lst;//直接赋值
	cout < < "lst2:" < < endl;
	PrintList(lst2);
	list< int > lst3;
	lst3.assign(5, 666);
	cout < < "lst3:" < < endl;
	PrintList(lst3);
	list< int > lst4;
	lst4.assign(lst3.begin(), lst3.end());//区间赋值
	cout < < "lst4:" < < endl;
	PrintList(lst4);
	
	//互换元素
	lst4.swap(lst);
	cout < < "lst4:" < < endl;
	PrintList(lst4);
	cout < < "lst:" < < endl;
	PrintList(lst);
}
int main()
{
	test();
	system("pause");
}
wKgaomSxQL-AQFzcAAOAoFyWHDU802.png

4.list容器设置和获取大小

list容器也有获取元素个数函数size()和设置元素个数函数resize(),但list容器不存在获取容量capacity()。

检查容器是否为空可以使用empty()函数。

list容器元素个数:size()
指定元素个数:resize(int num);
			 resize(int num,elem); 指定大小,超出用elem补齐
判断容器是否为空:empty()

使用示例:

#include < iostream >
using namespace std;
#include < list >
void PrintList(const list< string >& p)
{
	for (list< string >::const_iterator ptr = p.begin(); ptr != p.end(); ptr++)
	{
		cout < < *ptr < < " ";
	}
	cout < < endl;
}
void test()
{
	list< string > lst;
	//插入数据
	lst.push_back("C++");
	lst.push_back("list容器");
	lst.push_back("学习");
	lst.push_back("示例");
	PrintList(lst);
	cout < < "list成员个数:" < < lst.size() < < endl;
	lst.resize(10, "c++");//指定大小
	PrintList(lst);
	cout < < "list成员个数:" < < lst.size() < < endl;
	lst.resize(2, "c++");//指定大小
	PrintList(lst);
	cout < < "list成员个数:" < < lst.size() < < endl;

	list< string > lst2;
	if (lst2.empty())
	{
		cout < < "lst2容器为空" < < endl;
	}

}
int main()
{
	test();
	system("pause");
}
wKgaomSxQaWAJF7GAAQXx5Zj4nc287.png

5.list容器插入与删除

list容器中插入与删除相关函数如下所示:


list插入:
	push_back();尾插
	push_front();//头插入
	insert(iterator pos,elem);//在指定位置插入elem
	insert(iterator pos,n,elem);//在指定位置插入n个elem
	insert(iterator pos,begin,endl);在指定位置插入一个区间
list删除:
	pop_back();//尾删
	pop_front();//头删除
	erase(iterator pos);//删除指定位置的内容
	erase(begin,end);//删除区间内容
	clear();//删除所有内容
	remov(elem);删除容器中所有的elem

使用示例:

#include < iostream >
using namespace std;
#include < list >
class Person
{
public:
	Person(string name, int age) :name(name), age(age) {

	}
	bool operator==(const Person &p);
	string name;
	int age;
};
ostream& operator< <(ostream& cout, Person p)
{
	cout < < "姓名:" < < p.name < < "t年龄:" < < p.age ;
	return cout;
}
bool Person::operator==(const Person &p)
{
	if (this- >age == p.age && this->name == p.name)return true;
	return false;
}
void PrintList(list< Person >& p)
{
	for (list< Person >::iterator ptr = p.begin(); ptr != p.end(); ptr++)
	{
		cout < < *ptr < < endl;
	}
}
void test()
{
	Person p1("小王",18);
	Person p2("小李", 18);
	Person p3("小刘", 18);
	Person p4("小林", 18);
	Person p5("小郭", 18);
	list< Person > lst;
	lst.push_back(p1);
	lst.push_back(p2);
	lst.push_back(p3);
	lst.push_back(p4);
	lst.push_back(p5);
	if (p1 == p1)
	{
		cout < < "相等" < < endl;
	}
	cout < < "lst成员信息:" < < endl;
	PrintList(lst);
	list< Person >::iterator ptr = lst.begin();
	ptr++;
	lst.insert(ptr, Person("it_阿水", 18));//从第一个位置插入数据
	cout < < "insert插入成员信息:" < < endl;
	PrintList(lst);

	list< Person > lst2;
	lst2.insert(lst2.begin(),lst.begin(), lst.end());//从头插入区间数据
	cout < < "insert插入区间信息:" < < endl;
	PrintList(lst2);
	ptr = lst2.begin();
	for (int i = 0; i < 3; i++)ptr++;
	lst2.insert(ptr, 3, p1);//指定位置插入3个成员
	cout < < "insert插入多个成员信息:" < < endl;
	PrintList(lst2);
	cout < < "list2元素个数:" < < lst2.size() < < endl;
	lst2.erase(lst2.begin());//删除第一个位置的成员
	lst2.pop_back();//删除最后一个成员
	cout < < "list2元素个数:" < < lst2.size() < < endl;
	PrintList(lst2);
	//lst2.remove(p1);

	list< int >lst3;
	lst3.push_back(10);
	lst3.push_back(10);
	lst3.push_back(3);
	lst3.push_back(10);
	lst3.push_back(3);
	lst3.remove(10);//删除所以的10
	for (list< int >::iterator ptr = lst3.begin(); ptr != lst3.end(); ptr++)
	{
		cout < < *ptr < < " ";
	}
	cout < < endl;
}
int main()
{
	test();
	system("pause");
}
wKgZomSxQjyAXjdJAAbRGGiR5fQ808.png

6.list容器数据存取

由于list容器底层是通过双向循环链表来实现的,成员空间都是通过指针域保存的,所以不支持[]和at()访问成员。

list容器的迭代器不支持随机访问。


list容器数据存取:
	back();//获取最后一个元素
	push_back();//从末尾插入
	front();//获取第一个元素
	push_front();从头插入
注意:由于list容器并不是一段连续的空间,所以不支持[]和at()访问成员
	  list容器的迭代器不支持随机访问,但是双向的

使用示例:

#include < iostream >
using namespace std;
#include < list >
void test()
{ 
	list< int > lst;
	//插入数据
	lst.push_back(10);
	lst.push_front(20);
	lst.push_back(30);
	cout < < "第一个元素:" < < lst.front() < < endl;
	cout < < "最后一个元素:" < < lst.back() < < endl;
	list< int >::iterator ptr = lst.begin();
	ptr++;//支持往后
	ptr--;//支持往前
	//ptr += 3;错误,不支持随机访问

}
int main()
{
	test();
	system("pause");
}
wKgaomSxQziAGWOOAAL38P_I8RE723.png

7.list容器数据反转与排序

list容器自带排序函数sort(),默认是升序排序。


list容器反转:
	reverse();//反转(逆序)
list容器排序
	sort();//成员函数
注意:所有不支持迭代器随机访问的容器都不能使用全局函数sort进行排序,一般该容器会自带排序的成员函数

使用示例:


#include < iostream >
using namespace std;
#include < list >
void PrintList(list< int >& p)
{
	for (list< int >::iterator ptr = p.begin(); ptr != p.end(); ptr++)
	{
		cout < < *ptr < < " ";
	}
	cout < < endl;
}
bool mycompare(int v1, int v2)
{
	return v1 > v2;
}
void test()
{
	list< int > lst;
	lst.push_back(10);
	lst.push_back(30);
	lst.push_back(20);
	lst.push_front(40);
	lst.push_front(60);
	lst.push_front(50);
	PrintList(lst);
	//反转
	lst.reverse();
	cout < < "lst反转后" < < endl;
	PrintList(lst);
	//排序
	lst.sort();//默认是升序
	cout < < "从小到大排序:" < < endl;
	PrintList(lst);
	//降序排序
	lst.sort(mycompare);
	cout < < "从大到小排序:" < < endl;
	PrintList(lst);
}
int main()
{
	test();
	system("pause");
}
wKgZomSxRL2AW1_ZAAPpWb-KwFU685.png

8.list容器自定义数据类型排序案例

Person数据保存每个用户的姓名、年龄、身高,现在需要对年龄按升序排序,若年龄相同,则对按身高进行降序排序。

#include < iostream >
using namespace std;
#include < list >
class Person
{
public:
	Person(string name, int age, int height) :name(name), age(age), height(height) {
	}
	string name;//姓名
	int  age;//年龄
	int height;//身高
};
ostream& operator< <(ostream& cout, Person p)
{
	cout < < "姓名:" < < p.name < < "t年龄:" < < p.age < < "t身高:" < < p.height;
	return cout;
}
void PrintList(list< Person >& p)
{
	for (list< Person >::iterator ptr = p.begin(); ptr != p.end(); ptr++)
	{
		cout < < *ptr < < endl;
	}
}
/*
按照年龄升序排序,年龄相同时按升高降序排序
*/
bool PersonCompare(Person& p1, Person& p2)
{
	if (p1.age == p2.age)
	{
		return p1.height > p2.height;
	}
	return p1.age < p2.age;
}
void test()
{
	list< Person > lst;
	lst.push_back(Person("小王", 18, 170));
	lst.push_back(Person("小刘", 18, 175));
	lst.push_back(Person("小李", 23, 168));
	lst.push_back(Person("小林", 20, 171));
	lst.push_back(Person("小蒋", 18, 172));
	lst.push_back(Person("小姜", 17, 176));
	PrintList(lst);
	cout < < "排序后:" < < endl;
	lst.sort(PersonCompare);
	PrintList(lst);

}
int main()
{
	test();
	system("pause");
}
wKgaomSxRY2AR9s-AAWCZ2kW4yM283.png
审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    3911

    浏览量

    61313
  • 容器
    +关注

    关注

    0

    文章

    481

    浏览量

    21884
  • C++
    C++
    +关注

    关注

    21

    文章

    2066

    浏览量

    72902
收藏 人收藏

    评论

    相关推荐

    C++力扣刷题记盛最多的水容器,让我们从C++做题到放弃

    C++
    电路设计
    发布于 :2023年01月05日 15:49:23

    C++小白自学基础课简单的C++程序helloworld02

    C++
    电子学习
    发布于 :2023年01月12日 22:27:52

    C++零基础教程STL容器stack容器,轻松上手C++STL

    编程语言C++语言
    电子学习
    发布于 :2023年01月14日 11:27:23

    C++零基础教程STL容器tuple,轻松上手C++STL

    编程语言C++语言
    电子学习
    发布于 :2023年01月14日 11:29:21

    C++零基础教程STL容器initializer_list,轻松上手C++STL

    编程语言C++语言
    电子学习
    发布于 :2023年01月14日 11:30:27

    C++零基础教程STL容器bitset,轻松上手C++STL

    编程语言C++语言
    电子学习
    发布于 :2023年01月14日 11:31:34

    C++零基础教程STL容器queue容器,轻松上手C++STL

    编程语言C++语言
    电子学习
    发布于 :2023年01月14日 11:41:21

    C++零基础教程STL容器deque容器,轻松上手C++STL

    编程语言C++语言
    电子学习
    发布于 :2023年01月14日 11:41:55

    MSP430裸奔框架C++程序源码(菜农C++裸奔大法系列之一) 转载

    /*------------------------------------------------------------------------MSP430裸奔框架C++程序源码(菜农C++裸奔大法)本程序主要表现了
    发表于 02-01 11:06

    ccs如何使用C语言的“容器”?

    c++/c标准库有一个“容器”的东西,“vector”。我现在用的是ccs3.3,已经发现在安装路径下有“vector.h”的头文件,以及相应的“vector”文件,但是我不知道怎么使用。英文说明是直接将该头文件包含进来就行,但
    发表于 05-08 19:49

    C++标准库学习笔记重点

    容器:(1)array:在建立时指明size大小,使用中不能改变元素个数,只能改变数值。(2)deque:可以向两端发展,但在中间插值则比较麻烦。(3)vector、listlist相比
    发表于 10-23 20:28

    C/C++开源库及示例代码简介

    C/C++ 开源库及示例代码Table of Contents说明1 综合性的库2 数据结构 & 算法2.1 容器2.1.1 标准容器2.1.2 Lockfree 的
    发表于 08-20 08:23

    详细剖析C++的的3种容器

    容器是随着面向对象语言的诞生而提出的,容器类在面向对象语言中特别重要,甚至它被认为是早期面向对象语言的基础。在现在几乎所有的面向对象的语言中也都伴随着一个容器集,在C++ 中,就是标准
    的头像 发表于 01-09 12:57 4644次阅读
    详细剖析<b class='flag-5'>C++</b>的的3种<b class='flag-5'>容器</b>

    什么是list

    list 容器,又称双向链表容器,即该容器的底层是以双向链表的形式实现的。这意味着,list 容器
    的头像 发表于 02-27 15:52 1110次阅读

    C++学习笔记之顺序容器

    C++中的顺序容器是一种用于存储和管理元素序列的数据结构。它们提供了一组有序的元素,并支持在序列的任意位置插入和删除元素。C++标准库中提供了多种顺序容器,包括vector、deque
    的头像 发表于 05-11 17:05 408次阅读