『C++』list容器的简单介绍

list简单介绍

在这里插入图片描述
看到英文不要慌,翻译在下面(O(∩_∩)O哈哈~):

  1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代
  2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素
  3. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,以让其更简单高效
  4. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)。

在这里插入图片描述

list的使用

构造函数

构造函数接口说明
list();构造空的list
list(size_type n, const value_type& val = value_type());构造的list中包含n个值为val的元素
list(const list& x);拷贝构造函数
list(InputIteratot first, InputIterator last);用[first, last)区间中的元素构造list
#include <iostream>
#include <list>

int main(){
	std::list<int> l1;

	std::list<int> l2(4, 100);

	std::list<int> l3(l2);

	std::list<int> l4(l3.begin(), l3.end());

	for(auto e : l1){
		std::cout << e << " ";
	}
	std::cout << std::endl;

	for(auto e : l2){
		std::cout << e << " ";
	}
	std::cout << std::endl;

	for(auto e : l3){
		std::cout << e << " ";
	}
	std::cout << std::endl;

	for(auto e : l4){
		std::cout << e << " ";
	}
	std::cout << std::endl;

	return 0;
}
[sss@aliyun list]$ g++ constructor.cc -o constructor -std=c++11
[sss@aliyun list]$ ./constructor 

100 100 100 100 
100 100 100 100 
100 100 100 100 

迭代器

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

注意

  • begin和end为正向迭代器,对迭代器进行++操作,迭代器向后移动
  • rbegin和rend为反向迭代器,对迭代器进行++操作,迭代器向前移动
#include <iostream>
#include <list>

void ListDiaplsy(const std::list<int>& l){
	std::list<int>::const_iterator cit = l.begin();
	while(cit != l.end()){
		std::cout << *cit << " ";
		++cit;
	}
	std::cout << std::endl;
}

int main(){
	std::list<int> l1;

	l1.push_back(1);
	l1.push_back(2);
	l1.push_back(3);

	std::list<int>::iterator it = l1.begin();
	while(it != l1.end()){
		std::cout << *it << " ";
		++it;
	}
	std::cout << std::endl;

	std::list<int>::reverse_iterator rit = l1.rbegin();
	while(rit != l1.rend()){
		std::cout << *rit << " ";
		++rit;
	}
	std::cout << std::endl;

	ListDiaplsy(l1);

	return 0;
}
[sss@aliyun list]$ !g++
g++ iterator.cc -o iterator
[sss@aliyun list]$ ./iterator 
1 2 3 
3 2 1 
1 2 3 

容量相关接口

函数声明接口说明
bool empty();检测list是否为空,是返回true,否则返回false
size_t size();返回list中有效结点的个数
#include <iostream>
#include <list>

int main(){
	std::list<int> l1;

	l1.push_back(1);

	std::cout << l1.empty() << std::endl;
	std::cout << l1.size() << std::endl;

	return 0;
}
[sss@aliyun list]$ g++ capacity.cc -o capacity
[sss@aliyun list]$ ./capacity 
0
1

元素相关接口

函数声明接口说明
front();返回list的第一个节点中值的引用
back();返回list的最后一个结点中值的引用
#include <iostream>
#include <list>

int main(){
	std::list<int> l1;

	l1.push_back(1);
	l1.push_back(2);

	std::cout << l1.front() << std::endl;
	std::cout << l1.back() << std::endl;

	return 0;
}
[sss@aliyun list]$ g++ element.cc -o element
[sss@aliyun list]$ ./element 
1
2

修改操作

函数声明接口说明
void push_front( const T& value ); 在list首元素前插入值为val的元素
void pop_front();删除list中第一个元素
void push_back( const T& value );在list尾部插入值为val的元素
void pop_back();删除list中最后一个元素
iterator insert( iterator pos, const T& value );在list pos位置中插入值为val的元素
iterator erase( iterator pos );删除list pos位置的元素
void swap( list& other );交换两个list的元素
void clear();清空list中的有效元素
#include <iostream>
#include <list>

void PushPopTest(){
	std::list<int> l1;

	l1.push_back(1);
	l1.push_back(2);
	l1.push_back(3);
	l1.push_front(10);
	l1.push_front(20);
	l1.push_front(30);

	for(auto e : l1){
		std::cout << e << " ";
	}
	std::cout << std::endl;

	l1.pop_back();
	l1.pop_front();

	for(auto e : l1){
		std::cout << e << " ";
	}
	std::cout << std::endl;
}

void InsertEraseTest(){
	std::list<int> l1;

	l1.insert(l1.begin(), 1);
	for(auto e : l1){
		std::cout << e << " ";
	}
	std::cout << std::endl;

	l1.erase(l1.begin());
	for(auto e : l1){
		std::cout << e << " ";
	}
	std::cout << std::endl;
}

void SwapTest(){
	std::list<int> l1;
	l1.push_back(1);

	std::list<int> l2;
	l2.push_back(2);

	l1.swap(l2);
	std::cout << "l1: ";
	for(auto e : l1){
		std::cout << e << " ";
	}
	std::cout << std::endl;

	std::cout << "l2: ";
	for(auto e : l2){
		std::cout << e << " ";
	}
	std::cout << std::endl;
}

void ClearTest(){
	std::list<int> l1;
	l1.push_back(1);
	l1.push_back(2);

	for(auto e : l1){
		std::cout << e << " ";
	}
	std::cout << std::endl;

	l1.clear();

	for(auto e : l1){
		std::cout << e << " ";
	}
	std::cout << std::endl;
}

int main(){
	std::cout << "Push Pop: " << std::endl;
	PushPopTest();
	std::cout << std::endl;

	std::cout << "Insert Erase: " << std::endl;
	InsertEraseTest();
	std::cout << std::endl;

	std::cout << "Swap: " << std::endl;
	SwapTest();
	std::cout << std::endl;

	std::cout << "Clear: " << std::endl;
	ClearTest();
	std::cout << std::endl;

	return 0;
}
[sss@aliyun list]$ g++ modifiers.cc -o modifiers -std=c++11
[sss@aliyun list]$ ./modifiers 
Push Pop: 
30 20 10 1 2 3 
20 10 1 2 

Insert Erase: 
1 


Swap: 
l1: 2 
l2: 1 

Clear: 
1 2 


迭代器失效

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

失效情况

#include <iostream>
#include <list>

int main(){
	std::list<int> l1;

	l1.push_back(1);
	l1.push_back(2);
	l1.push_back(3);

	std::list<int>::iterator it = l1.begin();
	while(it != l1.end()){
		l1.erase(it);
		++it;
	}

	for(auto e : l1){
		std::cout << e << " ";
	}
	std::cout << std::endl;

	return 0;
}
[sss@aliyun list]$ g++ invalid_iterator.cc -o invalid_iterator -std=c++11
[sss@aliyun list]$ ./invalid_iterator 
Segmentation fault

修改后

#include <iostream>
#include <list>

int main(){
	std::list<int> l1;

	l1.push_back(1);
	l1.push_back(2);
	l1.push_back(3);

	std::list<int>::iterator it = l1.begin();
	while(it != l1.end()){
		it = l1.erase(it);
		++it;
	}

	for(auto e : l1){
		std::cout << e << " ";
	}
	std::cout << std::endl;

	return 0;
}
[sss@aliyun list]$ !g++
g++ invalid_iterator.cc -o invalid_iterator -std=c++11
[sss@aliyun list]$ ./invalid_iterator 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值