【C++】提高编程——03STL常用容器——list容器

7 list容器

7.1 list 容器基本概念

  功能:将数据进行链式存储
  定义:
  list(链表)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的
  链表的组成:
  链表由一系列节点组成。
  节点的组成:
  一个是存储数据元素的数据域,另一个是存储下一个阶段地址的指针域

  STL中的列表是一个双向循环列表
  链表优点:
  (1)采用动态存储分配,不会造成内存浪费和溢出
  (2)链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素

  链表缺点:
  链表灵活,但是空间(指针域)和时间(遍历)额外耗费大。容器遍历速度没有数组快(地址连续),并且占用的空间比数组大。

  STL中的链表是一个双向循环列表:
在这里插入图片描述
  由于链表的存储放射式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器
  list有一个重要的性质,插入和删除操作都不会造成原有list迭代器的失效,这在vector中是不成立的。
  总结:STL中list和vector是两个最常用的容器,各有优缺点。

7.2 list 构造函数

  功能:创建list容器
  函数原型:
  (1)list< T > lit;——list采用模板类实现,默认构造函数
  (2)list (beg,end);——构造函数将[beg,end}区间中的元素拷贝给本身
  (3)list(n,elem);——构造函数将n个elem拷贝给本身
  (4)list(const list &lst);——拷贝构造函数

#include <iostream>
using namespace std;

//包含容器头文件
# include<list>

void printList(const list<int>& l)
{
	for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test01()
{
	//1.默认构造函数构造:list< T > lit;
	list<int> l;
	l.push_back(10);
	l.push_back(21);
	l.push_back(14);
	l.push_back(23);
	printList(l);

	//2.按照区间的方式进行构造:list (beg,end);
	list<int>l2(l.begin(), l.end());
	printList(l2);

	//3.n个elem方式
	list<int>l3(6, 24);
	printList(l3);

	//4.拷贝构造函数
	list<int> l5(l);
	printList(l5);
}

int main()
{
	test01();
}

  总结:list构造方式同其它几个STL常用容器类似,熟练掌握即可

7.3 list 赋值和交换

  功能描述:给list容器进行
  (1)赋值(=或l.assign()
  (2)交换list容器(l.swap())

  函数原型:
  (1)l.assign(beg,end);——将[beg,end}区间中的元素赋值给本身
  (2)list &operator= (const list&lst);——重载=运算符
  (3)l.assign(n,elem);——将n个elem拷贝给本身
  (4)l.swap(lst)——交换两个容器

#include <iostream>
using namespace std;

//包含容器头文件
# include<list>

void printList(const list<int>& l)
{
	for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test01()
{
	list<int> l;
	l.push_back(10);
	l.push_back(21);
	l.push_back(14);
	l.push_back(23);
	printList(l);

	//1.将[beg,end}区间中的元素赋值给本身:l.assign(beg,end);
	list<int>l2;
	l2.assign(l.begin(), l.end());
	printList(l2);

	//2.n个elem方式:l.assign(n,elem)
	list<int>l3;
	l3.assign(5, 44);
	printList(l3);

	//3.重载=运算符的方式:
	list<int> l5=l;
	printList(l5);

	//4.两个容器互换:l.swap(lst);
	list<int>l6;
	l6.assign(10, 100);
	cout << "交换前两个容器!" << endl;
	printList(l6);
	printList(l);
	cout << "交换后两个容器!" << endl;
	l6.swap(l);
	printList(l6);
	printList(l);

}

int main()
{
	test01();
}

7.4 list 大小操作

  功能描述:对容器大小进行操作
  函数原型:
  (1)l.empty();——判断容器是否为空
  (2)l.size();——返回容器中元素个数
  (3)l.resize(int num);——重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则超出容器长度的元素被删除
  (5)l.resize(int num,elem);——重新指定容器的长度为num,若容器的长度变长,则以elem值填充新位置,如果容器变短则超出容器长度的原始将会被删除

#include <iostream>
using namespace std;

//包含容器头文件
# include<list>

void printList(const list<int>& l)
{
	for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test01()
{
	list<int> l;
	l.push_back(10);
	l.push_back(21);
	l.push_back(14);
	l.push_back(23);
	printList(l);

	//1.判断容器是否为空:l.empty()
	while (!l.empty())
	{
		cout << "list容器不为空!" << endl;
		//2.容器大小:l.size()
		cout << "容器大小为:" << l.size() << endl;

		//3.重新指定容器大小,若变长,则使用默认值填充,若变短,数据删除:l.resize(int num)
		l.resize(6);
		printList(l);

		//4.重新指定容器大小,若变长,则使用elem值填充,若变短,数据删除:l.resize(int num,elem)
		l.resize(4);
		printList(l);
		l.resize(6, 11);
		printList(l);
		break;
	}
}

int main()
{
	test01();
}

7.5 list 插入和删除

  功能描述:对list容器
  (1)插入(l.insert() )
  (2)删除(l.erase()

  函数原型:
  (1)两端插入操作:
  1.l.push_back(elem);——在容器尾部舔加一个数据
  2.l.push_front(elem);——在容器头部插入一个数据
  3.l.pop_back();——删除容器最后一个数据
  4.l.pop_front();——删除容器第一个数据
  (2)指定位置操作
  1.l.insert(pos,elem);——在pos位置插入一个elem元素的拷贝,返回新数据的位置
  2.l.insert(pos,n,elem);——在pos位置插入n个elem数据,无返回值
  3.l.insert(pos,beg,end);——在pos位置插入[beg,end)区间的数据,无返回值
  4.l.clear();——清空容器中的所有数据
  5.l.erase(beg,end);——删除[beg,end)区间的数据,返回下一个数据的位置
  6.l.erase(pos);——删除pos位置的数据,返回下一个数据的位置
  7.l.remove(elem);——删除容器中所有与elem匹配的元素
  上述位置pos,指的是迭代器的位置

#include <iostream>
using namespace std;

//包含容器头文件
# include<list>

void printList(const list<int>& l)
{
	for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
//(1)两端插入和删除操作
void test01()
{
	list<int> l;
	//1.在容器尾部舔加一个数据:l.push_back()
	l.push_back(10);
	l.push_back(21);
	//2.在容器头部插入一个数据:l.push_front()
	l.push_front(14);
	l.push_front(23);
	l.push_front(18);
	l.push_front(33);
	printList(l);
	//3.删除容器最后一个数据:l.pop_back()
	l.pop_back();
	//4.删除容器第一个数据:l.pop_front()
	l.pop_front();
	printList(l);
}
//(2)内部数据进行插入和删除操作
void test02()
{
	cout << "内部数据插入操作------------------》" << endl;
	list<int> l;
	l.push_back(11);
	l.push_back(23);
	l.push_front(44);
	l.push_front(21);
	l.push_front(15);
	l.push_front(33);
	printList(l);
	//(1)插入操作
	//1.在pos位置插入一个数据elem:l.insert(pos,elem)
	l.insert(l.begin(), 99);
	printList(l);
	//2.在pos位置插入n个数据elem:l.insert(pos,n,elem)
	l.insert(l.begin(),3,12);
	printList(l);
	//3.在pos位置在pos位置插入[beg,end)区间的数据:l.insert(pos,beg,end);
	list<int>l2;
	l2.insert(l2.begin(), l.begin(), l.end());
	printList(l2);

	//(2)删除操作
	cout << "内部数据删除操作------------------》" << endl;
	printList(l);
	//1.删除pos位置的数据:l.erase(pos)
	list<int>::iterator it = l.begin();
	it++;
	l.erase(it);
	printList(l);
	//2.删除[beg,end)区间的数据:l.erase(beg,end);
	l.erase(++l.begin(), --l.end());
	printList(l);

	//3.清空容器中数据:l.clear()
	l.clear();
	printList(l);

	//4.删除容器中所有与elem匹配的数据:l.remove(elem);
	list<int> ll;
	ll.push_back(23);
	ll.push_back(11);
	ll.push_back(23);
	ll.push_back(22);
	printList(ll);
	ll.remove(11);
	printList(ll);
}
int main()
{
	test01();
	test02();
}

7.6 list 数据存取

  功能描述:对list容器中的数据进行存取
  函数原型:
  (1)l.front();——返回容器第一个元素
  (2)l.back();——返回容器最后一个元素
  list本质是链表,不是用连续线性空间存储数据,迭代器也不支持随机访问,因此不可以用[]或者at来进行访问元素

#include <iostream>
using namespace std;

//包含容器头文件
# include<list>

void printList(const list<int>& l)
{
	for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test01()
{
	list<int> l;
	l.push_back(10);
	l.push_back(21);
	l.push_front(14);
	l.push_front(23);
	l.push_front(18);
	l.push_front(33);
	printList(l);
	
	//1.访问list容器中第一个元素:l.front()
	cout << "list容器中第一个元素:" << l.front() << endl;

	//2.访问list容器中最后一个元素:l.back()
	cout << "list容器中最后一个元素:" << l.back() << endl;

	//迭代器不支持随机访问(it+1错误),支持双向访问
	list<int>::iterator it = l.begin();
	it++;
	it--;//支持双向
}

int main()
{
	test01();
}

  总结:
  (1)list不支持[]或at方式访问数据
  (2)返回第一个元素front(),返回最后一个元素back()

7.7 list 翻转和排序

  功能描述:将容器中的元素翻转(l.reverse()),将容器中的数据进行排序(l.sort()
  函数原型:
  (1)l.reverse();——容器中元素翻转
  (2)l.sort();——容器中元素排序

#include <iostream>
using namespace std;

//包含容器头文件
# include<list>

void printList(const list<int>& l)
{
	for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test01()
{
	list<int> l;
	l.push_back(10);
	l.push_back(21);
	l.push_front(14);
	l.push_front(23);
	l.push_front(18);
	l.push_front(33);
	printList(l);

	//1.list容器中数据翻转:l.reverse();
	cout << "list数据翻转!" << endl;
	l.reverse();
	printList(l);
	//2.list容器中数据排序:l.sort()
	cout << "list数据排序!" << endl;
	//sort(l.begin(),l.end());//不可以使用,因为不支持随机访问的迭代器,不能使用标准算法
	l.sort();
	printList(l);
}

int main()
{
	test01();
}

7.8 list排序案例

  案例描述:将Person自定义数据类型进行排序,Person中属性有姓名,年龄,身高
  排序规则:按照年龄进行升序,如果年龄相同按照身高进行降序
  注意:自定义数据类型排序时必须指定排序规则,自己写写回调函数或者仿函数。sort()函数的参数中,填写该回调函数或者仿函数的函数名称。

#include <iostream>
using namespace std;

//包含容器头文件
# include<list>
#include<string>
class Person
{
public:
	string m_Name;
	int m_Age;
	int m_Height;
	Person(string name,int age,int height)
	{
		this->m_Name = name;
		this->m_Age = age;
		this->m_Height = height;
	}

};
//打印容器中数据
void printList(list<Person> &l)
{
	for (list<Person>::iterator it = l.begin(); it != l.end(); it++)
	{
		cout << "姓名:" << (*it).m_Name << " " << "年龄:" << (*it).m_Age << " " << "身高:" << (*it).m_Height << endl;
	}
}
//指定排序规则
bool comparePerson(Person& p1, Person& p2)
{
	
	if (p1.m_Age == p2.m_Age)
	{
		//身高按照降序排序
		return p1.m_Height > p2.m_Height;
	}
	else
	{
		//按照年龄进行升序排序
		return p1.m_Age < p2.m_Age;
	}
	
}
void test01()
{
	//1.创建list容器
	list<Person> l;
	//2.准备数据
	Person p1("小王", 18, 180);
	Person p2("小刘", 19, 176);
	Person p3("小赵", 18, 181);
	Person p4("小张", 22, 184);
	Person p5("小李", 21, 178);
	//3.向容器中插入数据
	l.push_back(p1);
	l.push_back(p2);
	l.push_back(p3);
	l.push_back(p4);
	l.push_back(p5);
	//4.打印容器中的数据
	printList(l);
	//4.按照年龄进行升序
	cout << "排序后的效果——————————————————" << endl;
	//l.sort();//自定义数据类型排序,必须指定规则,写回调函数或者仿函数

	l.sort(comparePerson);//参数为自定义的排序规则
	printList(l);
}

int main()
{
	test01();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值