list类的使用方法

一、list的底层构造

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

2.list的底层是一个双向链表结构,list和forward_list非常相似:forward_list是单链表。只能朝前迭代;

3.list保留了链表的基本特性。

二、list的构造

函数名功能
list()构造空的list
list(szie_type n, const value_type &val = value_type())构造的list中包含n个值为val的元素
list(const list &x)拷贝构造函数
list(InputIterator first, InputIterator last)用(first, last)区间的元素构造list
void Test1()
{
	list<int> l1;//构造空的l1
	list<int> l2(4, 100);//构造四个值为一百的元素
	list<int> l3(l2.begin(), l2.end());//使用迭代器构造
	list<int> l4(l3);//拷贝构造

	int array[] = {33, 22, 11, 44};
	list<int> l5(array, array+sizeof(array) / sizeof(int));
	for(list<int>::iterator it = l5.begin(); it != l5.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
	for(auto& e : l5)
	{
		cout << e << " "; 
	}
	cout << endl;
}

二、list iterator的使用

函数名功能
begin()返回第一个元素的迭代器
end()返回最后一个元素下一个位置的迭代器
rbegin()返回第一个元素的reverse_iterator,即end位置
rend()返回最后一个元素下一个位置的reverse_iterator,即begin位置
cbegin()返回第一个元素的const_iterator
cend()返回最后一个元素下一个位置的const_iterator
rcbegin()返回第一个元素的const_reverse_iterator,即cend的位置
rcend()返回最后一个元素下一个位置的const_reverse_iterator,即cbegin的位置
void Test2()
{
	int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9 ,0};
	list<int> l (array, array+sizeof(array) / sizeof(array[0]));
	//使用正向迭代器正向打印list中的元素
	for(list<int>::iterator it = l.begin(); it != l.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
	//使用反迭代器反向打印list中的元素
	for(list<int>::reverse_iterator it = l.rbegin(); it != l.rend(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
	//const正向迭代器
	for(list<int>::const_iterator cit = l.cbegin(); cit != l.cend(); ++cit)
	{
		cout << *cit << " ";
	}
	cout << endl;
	auto cit = l.cbegin();
	cout << typeid(cit).name() << endl;
}

三、容量

函数声明功能
bool empty()const检测list是否为空,是返回true,否返回false
size_t size()const返回list中有效节点的个数

注:list不再有capacity的说法,list的节点都是动态开辟的,所以只有size.

void Test3()
{
	int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
	list<int> l(array, array+sizeof(array) / sizeof(array[0]));
	cout << l.size() << endl;
	if(l.empty())
		cout << "空的list" << endl;
	else
	{
		for(list<int>::iterator it = l.begin(); it != l.end(); ++it)
			cout << *it << " ";
		cout << endl;
	}
}

四、list element access

函数声明功能
reference front()返回list的第一个节点中值的引用
const_reference front()const返回list的第一个节点中值的const引用
reference back()返回list的最后一个节点中值的引用
const_reference back()const返回list的最后一个节点中值的const引用
void Test4()
{
	int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
	list<int> l1(array, array+sizeof(array) / sizeof(array[0]));
	l1.front() = 10;
	l1.back() = 10;
	for(list<int>::iterator it = l1.begin(); it != l1.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
	const list<int> l2(array, array+sizeof(array) / sizeof(array[0]));
	const int& a = l2.back();
	cout << a << endl;
}

注:因为返回的是引用,所以可以任意修改该位置的值;

当对象的是const类型时,其front()为const引用类型。

五、list增删查改

函数声明功能
void push_front(const value_type &val)在list首元素插入值为val的元素
void pop_front()删除list的第一个元素
void push_back(const value_type &val)在list尾部插入值为val的元素
void pop_back()删除list最后一个元素

template<class..Args>

void emplace_front(Args&&.. args)

在list第一个元素前根据参数直接构造元素

template<class..Args>

void emplace_back(Args&&.. args)

在list最后一个元素后根据参数直接构造元素

template<clss..Args>

iterator emplace(const_iterator position, Args&&..args)

在链表的任意位置根据参数直接构造元素
iterator insert(ierator position, const value_type &val)在list的position位置插入值为val的元素
void insert(iertaor position, size_type n, const value_type &val)在list的position位置插入n个值为val的元素
void insert(ierator position, InputIterator first,InputIterator last)在list的position位置插入[first, last)区间中的元素
iterator erase(iterator position)删除list的position位置的元素
iterator rase(iterator first, iterator last)删除list中[first, last)区间的元素
void swap(list &x)交换两个list中的元素
void resize(size_type n, value_type val = value_type())将list中有效元素个数改变到n个,多处的元素用val填充
void clear()情况list中的有效元素
void Test5()
{
	int array[] = {1, 3, 4};
	list<int> l(array, array+sizeof(array) / sizeof(array[0]));
	l.push_back(6);
	Print(l);
	l.pop_back();
	Print(l);
}
void Print(list<int>& l)
{
	for(list<int>::iterator it = l.begin(); it != l.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		,_day(day)
	{}
	Date(const Date& d)
		: _year(d._year)
		, _month(d._month)
		, _day(d._day)
	{
		cout << "Data(const Date&):" << this << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
void Test6()
{
	list<Date> l;
	Date d(2018, 11, 27);
	//先构造好元素,然后将元素拷贝到节点中,插入时先调用构造函数,再调拷贝构造函数
	l.push_back(d);
	//先构造结点,然后调用构造函数在节点中直接构造对象
	//emplace_back比push_back效率更高,少调用了一次拷贝构造函数
	l.emplace_back(28);
	l.emplace_front(29);
}
void Test7()
{
	int array[] = {1, 2, 3};
	list<int> l(array, array+sizeof(array) / sizeof(array[0]));
	//获取链表的第二个节点
	//链表中的节点还是按照0,1,2的次序排列
	auto pos = ++l.begin();
	cout << *pos << endl;
	//在pos前插入值为4的元素
	l.insert(pos, 4);
	Print(l);
	//在pos前插入4个值为3的元素
	l.insert(pos, 4, 3);
	Print(l);
	//在pos前插入值为[v.begin(),v.end())区间的元素
	int array2[] = {7, 8, 9};
	vector<int> v(array2, array2+sizeof(array2) / sizeof(int));
	l.insert(pos, v.begin(), v.end());
	Print(l);
	//删除pos位置上的元素
	l.erase(pos);
	Print(l);
	//删除这个区间所有元素
	l.erase(++l.begin(), l.end()--);
	Print(l);
}
void Test8()
{
	//用数组来构造list
	int array[] = {1, 2, 3, 4, 5, 6};
	list<int> l(array, array+sizeof(array) / sizeof(array[0]));
	Print(l);
	l.resize(10);//注意:如果list中放置的是内置类型,默认值为0,如果list中放置的是自定义类型元素,需要调用缺省构造函数
	Print(l);
	l.resize(20, 4);
	Print(l);

	l.resize(10);
	Print(l);

	//用vector中的元素构造list
	int array2[] = {1, 2, 3, 4};
	vector<int> v(array2, array2+sizeof(array2) / sizeof(array2[0]));
	list<int> l2(v.begin(), v.end());
	Print(l2);
	l.swap(l2);
	Print(l);
	Print(l2);

	l2.clear();
	cout << l2.size() << endl;

}

六、list迭代器失效

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

//迭代器失效问题:迭代器的失效即迭代器所指向的节点无效,即该节点被删除了,
//因为list的底层结构为带头节点的双向链表,因此在list中进行插入时迭代器是不会失效的,
//只有在删除的时候才会失效,并且失效只是指向被删除节点的迭代器,其他迭代器不受影响。
//1、对于节点式容器(map, list, set)元素的删除,插入操作会导致指向该元素的迭代器失效,其他元素迭代器不受影响。
//2、对于顺序式容器(vector)元素的删除、插入操作会导致指向该元素以及后面的元素的迭代器失效。
void TestListIterator()
{
	int array[] = {1, 2, 3, 4, 5, 6};
	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++);
		it = l.erase(it);//两种方法相同,erase操作之后的返回值指向被删元素后的迭代器
	}
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值