第九层(7):STL之list(上)

简介: 第九层(7):STL之list(上)

前情回顾


在上一块石碑中,我学到了queue,同时下一块石碑也显露出来…


🚄上章地址:第九章(6):STL之queue


list


概念


list可以将数据链式存储,list也就是链表,链表是由一系列的节点组成,节点是内部有两块区域,一个是存放下一个节点地址的指针域,一个是存放数据的数据域,链表可以对任意位置进行快速的插入和删除,但是因为链表不是一块连续的空间,所以遍历的速度慢于数组,并且占用空间比数组要大,list的本质就是一个双向循环链表,双向循环列表指的就是,第一个节点记录着最后的位置,最后一个节点记录第一个节点的位置

0a2653c851af460fa595bd959398a8f1.png


由于链表的储存方法不是连续空间,所以list的迭代器只支持前移和后移,属于双向迭代器,不能随机访问


优缺点


优点:

采用动态存储分配,不会造成内存的浪费和溢出

list的插入和删除十分方便,只需要修改指针就可以,不需要移动内部的大量数据

list的插入和删除不会造成原有的迭代器失效,而vector不行,因为vector在插入扩展的时候,会找一片新空间将数据拷贝过去,

缺点:

相比较数组而言,链表所占用的空间较大,遍历消耗的额外时间较多


构造函数


list中的构造函数与vector一样,有四个构造函数

list< T >;//;默认构造函数
list(beg,end);//将迭代器beg到end之间的数据拷贝到本身
list(size_t n,T elem);//将n个elem赋值给本身
list(const list &l);//将l的元素拷贝到本身


使用:


#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
  for (list<int>::iterator b=l.begin(); b != l.end(); b++)
  {
  cout << *b << " ";
  }
  cout << endl;
}
void test1()
{
  list<int> l;
  list<int> l1(10, 1);
  print(l1);
  list<int>l2(l1);
  print(l2);
  list <int>l3(l1.begin(), l1.end());
  print(l3);
}
int main()
{
  test1();
  return 0;
}

0a2653c851af460fa595bd959398a8f1.png


赋值函数


list中的赋值操作与vector中也是一样的,有三种

list& operator=(const list &l);//操作符重载
assign(beg,end);//将迭代器beg到end的数据拷贝到本身
assign(int n,T elem);//将n个elem拷贝到本身


使用:


#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
  for (list<int>::iterator b=l.begin(); b != l.end(); b++)
  {
  cout << *b << " ";
  }
  cout << endl;
}
void test1()
{
  list<int> l(10, 1);
  print(l);
  list<int> l1;
  l1 = l;
  print(l1);
  list<int> l2;
  l2.assign(l1.begin(),l1.end());
  print(l2);
  list<int> l3;
  l3.assign(10, 2);
  print(l3);
}
int main()
{
  test1();
  return 0;
}

0eacb84100b54626af849e6b562bf92a.png


交换函数


与vector一样,可以利用swap函数进行交换

swap(list< T > &l);//将l的数据和本身进行交换


使用:


#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
  for (list<int>::iterator b=l.begin(); b != l.end(); b++)
  {
  cout << *b << " ";
  }
  cout << endl;
}
void test1()
{
  cout << "交换前" << endl;
  list<int> l(10, 1);
  print(l);
  list<int> l1;
  l1.assign(10, 2);
  print(l1);
  cout << "交换后" << endl;
  l.swap(l1);
  print(l);
  print(l1);
}
int main()
{
  test1();
  return 0;
}

2d65d23f6d4748949b924e4057485923.png


容器和大小操作


list比vector少一个容器大小,因为list的空间不是连续的,数据存放方式也与vector不同,有多少元素大小就多少,和vector不一样,所以不需要

size();//返回容器内元素个数
empty();//判断容器是否为空,为空返回真
resize(size_t num);///可以重新指定容器的容量,容量为num,若容器变长,则变长的部分全部补0,若变短,则将超出的部分全部删除
reszie(size_t num,T elem);//可以重新指定容器的容量,容量为num,若容器变长,则变长的部分全部补elem,若变短,则将超出的部分全部删除


使用:


#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
  for (list<int>::iterator b=l.begin(); b != l.end(); b++)
  {
  cout << *b << " ";
  }
  cout << endl;
}
void test1()
{
  list<int> l;
  if (l.empty())
  {
  cout << "l为空" << endl;
  }
  cout << l.size() << endl;
  l.assign(10, 1);
  print(l);
  l.resize(11);
  print(l);
  l.resize(15, 1);
  print(l);
}
int main()
{
  test1();
  return 0;
}

2e9b90b2ca334476abebe75bafe6eeaa.png


插入操作


list中,有五种插入操作,可以从头部插入,从尾部插入,还有insert的三个重载版本

push_front(T elem);//在头部插入elem
push_end(T elem);//在尾部插入elem
insert(pos,T elem);//在pos的位置插入一个elem,返回新数据的位置
insert(pos, size_t n,T elem);//在pos位置插入n个elem
insert(pos,beg,end);//在pos位置插入迭代器beg到end的数据


使用:


#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
  for (list<int>::iterator b=l.begin(); b != l.end(); b++)
  {
  cout << *b << " ";
  }
  cout << endl;
}
void test1()
{
  list<int> l;
  l.push_back(2);
  print(l);
  l.push_front(1);
  print(l);
  l.insert(l.end(), 3);
  print(l);
  l.insert(l.begin(), 1,0);
  print(l);
  list<int>::iterator b = l.begin();
  b++;
  l.insert(b, l.begin(), l.end());
  print(l);
}
int main()
{
  test1();
  return 0;
}


删除操作


删除操作有六个,向比较vector多了头部的删除,和一个删除一样元素的删除

pop_back();//删除尾部元素
pop_front();//删除头部元素
clear();//删除全部元素
erase(beg,end);//删除迭代器beg到end之间的数据
erase(pos);//删除迭代器pos位置的数据,返回下一个元素的位置
remove(T elem);//删除容器中所有的elem


使用:


#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
  for (list<int>::iterator b=l.begin(); b != l.end(); b++)
  {
  cout << *b << " ";
  }
  cout << endl;
}
void test1()
{
  list<int> l;
  for (int i = 0; i < 10; i++)
  {
  l.push_back(i);
  l.push_back(i);
  }
  print(l);
  l.pop_back();
  print(l);
  l.pop_front();
  print(l);
  list<int>::iterator b = l.begin();
  b++; b++; b++;
  l.erase(b);
  print(l);
  list<int>::iterator b1 = l.begin();
  b1++; b1++; b1++;
  l.erase(b1, l.end());
  print(l);
  l.remove(1);
  print(l);
  l.clear();
  print(l);
}
int main()
{
  test1();
  return 0;
}


0eacb84100b54626af849e6b562bf92a.png

0eacb84100b54626af849e6b562bf92a.png


相关文章
|
5天前
|
存储 编译器 C++
【C++/STL】list(常见接口、模拟实现、反向迭代器、)
【C++/STL】list(常见接口、模拟实现、反向迭代器、)
5 0
|
18天前
|
存储 缓存 编译器
【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比
【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比
|
18天前
|
算法 C++ 容器
【C++进阶(四)】STL大法--list深度剖析&list迭代器问题探讨
【C++进阶(四)】STL大法--list深度剖析&list迭代器问题探讨
|
1月前
|
编译器 C++ 容器
【C++初阶】STL详解(八)List的模拟实现
【C++初阶】STL详解(八)List的模拟实现
39 0
|
1月前
|
存储 C++ 容器
【C++初阶】STL详解(五)List的介绍与使用
【C++初阶】STL详解(五)List的介绍与使用
32 0
|
1月前
|
存储 C语言 C++
C++中STL常用容器(vector、deque、list、map、set)一文带你了解
C++中STL常用容器(vector、deque、list、map、set)一文带你了解
|
2月前
|
C++
【C++练级之路】【Lv.8】【STL】list类的模拟实现
【C++练级之路】【Lv.8】【STL】list类的模拟实现
|
2月前
|
存储 安全 Java
java集合框架及其特点(List、Set、Queue、Map)
java集合框架及其特点(List、Set、Queue、Map)
|
1天前
|
存储 安全 算法
Java一分钟之-Java集合框架入门:List接口与ArrayList
【5月更文挑战第10天】本文介绍了Java集合框架中的`List`接口和`ArrayList`实现类。`List`是有序集合,支持元素重复并能按索引访问。核心方法包括添加、删除、获取和设置元素。`ArrayList`基于动态数组,提供高效随机访问和自动扩容,但非线程安全。文章讨论了三个常见问题:索引越界、遍历时修改集合和并发修改,并给出避免策略。通过示例代码展示了基本操作和安全遍历删除。理解并正确使用`List`和`ArrayList`能提升程序效率和稳定性。
6 0
|
2天前
|
存储 安全 Java
Java容器类List、ArrayList、Vector及map、HashTable、HashMap
Java容器类List、ArrayList、Vector及map、HashTable、HashMap