C++STL list容器

1、list容器简介

  • 链表是一种物理存储单元上非连续非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
  • 链表由一系列结点(链表中每一个元素称为一个结点)组成,结点可以在运行时动态生成。
  • 每个结点包括两部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域
  • 相较于vector的连续线性空间,list的好处是每次插入或者删除一个元素,就配置或者释放一个元素的空间。list对空间的运用绝对精准,不浪费。
  • 对于任何位置的元素插入或删除,list永远是常数时间
  • 采用动态存储分配,不会造成内存浪费和溢出,链表的插入和删除只需要修改指针,不需要移动大量元素,但是空间和时间的额外耗费较大(这里理解为相较于vector容器,每一个节点需要额外空间存放指针域,另外每插入/删除一个元素都需要申请/释放一次空间,因此空间上和时间上的消耗相对较大)。
    在这里插入图片描述

2、list迭代器

  • list容器不能像vector一样以普通指针作为迭代器,因为其结点不能保证在同一块连续的内存空间上。list迭代器必须有能力指向list的结点,并有能力进行正确的递增(指向下一个结点)、递减(指向上一个结点)、取值(取结点的数据值)、成员存取(结点的成员)操作。
  • 由于list是双向链表,迭代器必须具备前移后移的能力,所以list容器提供的是双向迭代器(Bidirectional Iterator).
  • list插入和删除操作都不会造成原有list迭代器失效。这在vector是不成立的,因为vector插入操作可能造成空间重新配置,导致原有迭代器失效。list元素的删除,只有被删除的那个元素的迭代器失效,其他迭代器不受影响。

3、API

/************************构造函数****************************/
list<T> lstT;//list采用模板类实现,默认构造形式
list(beg,end);//构造函数将[beg,end)区间中的元素拷贝给本身
list(n,elem);//构造函数将n个elem拷贝给本身
list(const list& lst);//拷贝构造
/************************插入删除操作****************************/
push_back(elem);//在容器尾端插入元素
pop_back();//删除容器最后一个元素
push_front(elem);//在容器开头插入一个元素
pop_front();//在容器开头移除第一个元素
insert(pos,elem);//在pos位置插入元素elem,返回新数据的位置
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值
clear();//移除容器所有数据
erase(beg,end);//移除[beg,end)区间的数据,返回下一个数据的位置
erase(pos);//删除pos位置的数据,返回下一个数据的位置
remove(elem);//删除容器中所有与elem值匹配的元素
/************************大小操作****************************/
empty();//判断容器是否为空
size();//返回容器中元素的个数
resize(num);//重新指定容器的长度为num,若容器变长则以默认值填充,
             //若容器变短则末尾超出容器长度的元素将被删除
resize(num,elem);//重新指定容器的长度为num,若容器变长则以elem值填充,
             //若容器变短则末尾超出容器长度的元素将被删除
/***********************赋值操作****************************/
assign(beg,end);//将[beg,end)区间中的数据拷贝赋值给本身
assign(n,elem);//将n个elem拷贝赋值给本身
list& operator=(cosnt list& lst);//重载=运算符
swap(lst);//将lst与本身元素交换
/***********************数据存取****************************/
front();//返回第一个元素
back();//返回最后一个元素
/**********************************************************/
reverse();//反转链表
sort();//排序
  • 系统提供的sort算法仅支持随机访问迭代器,其格式为sort(beg,end),因此list提供了自己的sort算法。
  • 只有随机访问迭代器才支持+n的操作,因此对于list容器的双向迭代器不支持+n操作。而对于++操作随机访问迭代器和双向迭代器都支持。
  • list容器存放自定义数据,如果删除某个节点,必须重载= =运算符。(remove函数的实现需要用到==)
#include<iostream>
#include<list>
#include<vector>
#include<algorithm>
using namespace std;

class Person{
public:
    Person(string name,int age){
        this->name=name;
        this->age=age;
    } 
    bool operator==(const Person& ob){//成员函数重载==运算符
        if(this->name==ob.name&&this->age==ob.age)return true;
        return false;
    }
    bool operator<(const Person& ob){//成员函数重载<运算符
        return this->age<ob.age;
    }
};
//使用普通函数指定排序规则
bool myComparePerson(const Person& ob1,const Person& ob2){
    return ob1.age<ob2.age;
}
void printListPerson(list<Person>& L){
    for(list<Person>::iterator it=L.begin();it!=L.end();it++){
        cout<<(*it).name<<" "<<(*it).age<<endl;
    }
}
void printListPerson(vector<Person>& v){
    for(vector<Person>::iterator it=L.begin();it!=L.end();it++){
        cout<<(*it).name<<" "<<(*it).age<<endl;
    }
}
//仿函数
class Compare{
    public:
        bool operator()(const Person& ob,const Person& ob2){
            return ob.age<ob2.age;
        }
};
void test()
{
    list<Person> L;
    L.push_back(Person("小明",18));
    L.push_back(Person("小红",15));
    L.push_back(Person("小李",19));
    L.push_back(Person("小王",14));
    
    printListPerson(L);
    
    Person temp("小明"18);
    L.remove(temp);//删除数据,需要重载==运算符,因为remove函数中隐含了比较定位
    printListPerson(L);
    
    //list对于自定义数据排序,必须实现排序规则(需要重载<运算符)。
    //(可以用成员函数,也可以用普通函数)
    //返回真不交换,返回假则交换
    L.sort();//使用重载<运算符指定排序规则,按从小到大排序
    printListPerson(L);
        
    L.sort(myComparePerson);//使用普通函数指定排序规则(若函数中是大于符号,就会从大到小排序)
    printListPerson(L); 
    
    //vector对自定义数据排序,同样需要指定排序规则(推荐在成员函数中重载小于运算符)
    vector<Person> v;
    v.push_back(Person("小明",18));
    v.push_back(Person("小红",15));
    v.push_back(Person("小李",19));
    v.push_back(Person("小王",14));
    //默认方式比较从小->大
    sort(v.begin(),v.end());
    printListPerson(v); 
    //普通函数指定排序规则
    sort(v.begin(),v.end(),myComparePerson);
    printListPerson(v);
    //仿函数指定排序规则
    //Compare()为匿名对象,匿名对象传参时再与小括号结合触发仿函数(()运算符重载)
    sort(v.begin(),v.end(),Compare());
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值