C++ 11 STL list

list

list是C++标准模板库(STL)中的一个容器,用于存储元素的双向链表。它提供了高效的插入和删除操作,但在随机访问方面不如vector高效。

c++ 复制代码
//todo list

# include <iostream>
#include <list>
using namespace std;

void print(list<int> & li){
    //使用迭代器遍历list
    for(list<int>::iterator it=li.begin();it!=li.end();it++){
        cout<<*it<<" ";
    }
    cout<<endl;


}

int main() {
    list<int> li={1,2,3,4,5};
    cout<<li.front()<<endl;//1
    cout<<li.back()<<endl;//5
    print(li);


    li.push_back(6);//添加元素
    print(li); //1 2 3 4 5 6

    li.pop_back();//删除最后一个元素
    print(li); //1 2 3 4 5

    li.pop_front();//删除第一个元素
    print(li);//2 3 4 5

    li.sort();//排序
    print(li);//2 3 4 5

    li.reverse();//反转
    print(li);//5 4 3 2

    li.remove(3);//删除所有值为3的元素
    print(li);//2 4 5

    li.unique();//删除重复元素
    print(li);//2 4 5

    li.resize(1);//调整大小
    print(li);//2

    li.clear();//清空list
    print(li);

    li.insert(li.begin(),10);//在第一个位置插入元素
    print(li);//10

    li.erase(li.begin());//删除第一个元素
    print(li);//10

    
    return 0;
}
c++ 复制代码
# if 1
//todo list
#include <iostream>
#include <list>
using namespace std;


void print(list<int> & li){
    list<int> ::iterator it ;

    for (it=li.begin();it!=li.end();++it){
        cout<<*it<<" ";
    }
    cout<<endl;
}

int main(){
    int arr[10]={1,2,3,4};
    list<int> li(arr,arr+4);
    list<int> li2(li.begin(),li.end());
    print(li);
    print(li2);

    cout<<li2.size()<<endl;//4
    while (!li2.empty()){
        cout<<li2.back();
        li2.pop_back();
    }
    cout<<li2.size()<<endl;//0

    
    return 0;
}


# endif

list 比较

比较对象要重载==和!=运算符

c++ 复制代码
int main(){

    //比较基本数据类型
    list<int> li1={1,2,3,4};
    list<int> li2={1,2,3,4};

    if(li1==li2){
        cout<<"=="<<endl;
    } else{
        cout<<"!="<<endl;
    }

    //比较对象要重载==和!=运算符
    
    return 0;
}

插入

c++ 复制代码
#include <iostream>
#include <list>
#include <iterator>
using namespace std;

void print(list<int> & li){
    //for(auto it=li.begin();it!=li.end();++it){  cout<<*it<<" ";  }

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

}
int main(){
    list<int> li={1,2,3,4,5};
    li.insert(li.begin(),333);//开头插入333
    print(li);//333 1 2 3 4 5
    li.insert(li.end(),2,666);//末尾插入2个666
    print(li);//333 1 2 3 4 5 666 666

    int arr[]={6,7,8};
    li.insert(li.end(),arr,arr+3);//插入一个范围
    print(li);//333 1 2 3 4 5 666 666 6 7 8

    li.insert(li.end(),{77,77,77});//插入一个范围
    print(li);//333 1 2 3 4 5 666 666 6 7 8 77 77 77

    li.emplace(li.begin(),111);//在开头插入111
    print(li);//111 333 1 2 3 4 5 666 666 6 7 8 77 77 77

    li.emplace_back(222);//在末尾插入222
    print(li);//111 333 1 2 3 4 5 666 666 6 7 8 77 77 77 222

    li.emplace_front(333);//在开头插入333
    print(li);//333 111 333 1 2 3 4 5 666 666 6 7 8 77 77 77 222

    return 0;
}

删除

erase删除元素

c++ 复制代码
#include <iostream>
#include <list>
#include <iterator>
using namespace std;

void print(list<int> & li){
    //for(auto it=li.begin();it!=li.end();++it){  cout<<*it<<" ";  }
    for(list<int>::iterator it =li.begin();it!=li.end();++it){
        cout<<*it<<" ";
    }
    cout<<endl;
}

int main(){
    list<int> li={1,2,3,4,5};

    li.erase(li.begin());//删除第一个元素
    print(li);//2 3 4 5

    //list并非线性,所以不能+1
    //li.erase(li.begin()+1);

    list<int>::iterator it=li.begin();//获取迭代器
    advance(it,1);//移动到第二个元素
    li.erase(it);//删除第二个元素
    print(li);//2 4 5

    //支持 ++ -- 前缀和后缀运算符
    li.erase(++li.begin());//删除第二个元素
    print(li);//2 5

    //删除范围
    li.erase(li.begin(),li.end());//删除所有元素
    print(li);//(空)

    return 0;
}

remove删除元素

c++ 复制代码
//todo remove删除元素
#include <iostream>
#include <list>
#include <iterator>
using namespace std;

void print(list<int> & li){
    //for(auto it=li.begin();it!=li.end();++it){  cout<<*it<<" ";  }
    for(list<int>::iterator it =li.begin();it!=li.end();++it){
        cout<<*it<<" ";
    }
    cout<<endl;
}

int main(){
    list<int> li={1,2,3,4,5};

    li.remove(3);//删除所有值为3的元素
    print(li);//1 2 4 5
    cout<<li.size()<<endl;//4

    //删除>=3的元素
    li.remove_if([](int x){
        if(x>=3)return true;
        else return false;
    });//返回值是bool的函数
    print(li);//1 2
    cout<<li.size()<<endl;//2
    return 0;
}

list 特有

排序

基本类型

c++ 复制代码
//todo list排序
#include <iostream>
#include <list>
#include <iterator>
using namespace std;

void print(list<int> & li){
    //for(auto it=li.begin();it!=li.end();++it){  cout<<*it<<" ";  }
    for(list<int>::iterator it =li.begin();it!=li.end();++it){
        cout<<*it<<" ";
    }
    cout<<endl;
}

int main(){
    list<int> li={5,3,1,4,2};

    li.sort(less<int>());
    li.sort();//默认less<int>()
    print(li);//1 2 3 4 5
    li.sort(greater<int>());
    print(li);//5 4 3 2 1

    //greater_equal是greater的升级版,即>= 
    li.sort(greater_equal<int>());
    //less_equal是less的升级版,即<=
    li.sort(less_equal<int>());
    
    return 0;
    
}

对象排序 和 取反not2

c++ 复制代码
//todo 排序对象
#include <iostream>
#include <list>

using namespace std;

class A
{
public:
    A()
    {
        cout<<"无参构造函数"<<this<<endl;
    }
    A(int i):_data(i)
    {
        cout<<"有参构造函数"<<this<<endl;
    }
    A(const A & other)
    {
        this->_data=other._data;
        cout<<"拷贝构造"<<this<<" from "<<&other<<endl;
    }
    A& operator=(const A & other)
    {
        this->_data=other._data;
        cout<<"拷贝赋值"<<this<<" from "<<&other<<endl;
        return *this;
    }
    ~A()
    {
        cout<<"析构函数"<<this<<endl;
    }

    //重载<运算符
    bool operator<(const A & other) const
    {
        return _data<other._data;
    }
    void print(){
        cout<<_data<<" ";
    }
private:
    int _data;
};

int main(){
    list<A> li={A(3),A(2),A(1)};
    li.sort(less<A>());//需要重载<运算符
    for (auto & it:li){
        it.print();
        cout<<endl;  // 1   2    3
    }

    //使用not1单参数的时候取反
    //使用not2两个参数的时候取反
    li.sort(not2(less<A>()));//取反
    for (auto & it:li){
        it.print();
        cout<<endl; // 3   2    1
    }
    return 0;
}

unique删除重复元素

c++ 复制代码
//todo unique删除重复元素
#include <iostream>
#include <list>

using namespace std;


int main(){
    list<int> li={1,2,3,3,4,5,5,4,3,2,1};
    //li.unique();//去除了连续的重复元素
    for (auto & it:li){
        cout<<it<<" "; //1 2 3 4 5 4 3 2 1
    }
    cout<<endl;

    li.sort();//先排序
    li.unique();//再去重
    for (auto & it:li){
        cout<<it<<" "; //1 2 3 4 5
    }
    cout<<endl;

    //自定义比较函数
    li.unique([](int a,int b){
        if(a==b ){
            return true;
        }else{
            return false;
        }
    });


    return 0;
}

拼接相关操作

c++ 复制代码
//todo 拼接相关操作
# include <iostream>
# include <list>
using namespace std;

void print(list<int> & li){
    for(auto it=li.begin();it!=li.end();++it){
        cout<<*it<<" ";
    }
    cout<<endl;
}

int main(){
    list<int> li1={1,2,3,4,5};
    list<int> li2={6,7,8,9,10};


    //li1.splice(li1.begin(),li2);//拼接到末尾
    //print(li1);//6 7 8 9 10 1 2 3 4 5
    //print(li2);//拼接时发生移动,li2移动到li1,li2为空

//    li1.splice(li1.end(),li2,li2.begin());
//    print(li1);//1 2 3 4 5 6
//    print(li2);//7 8 9 10

//    auto itr=li1.begin();
//    advance(itr,3);//移动到第四个元素
//    li1.splice(itr,li2,li2.begin(),li2.end());
//    print(li1);//1 2 3 6 7 8 9 10 4 5

    list<int> li3={100,244,37,4,5};
    list<int> li4={61,7,5558,97,10};

    //需要merge有序需要先排序再merge
    li3.merge(li4);//61 7 100 244 37 4 5 5558 97 10
    print(li3);//1 2 3 4 5 6 7 8 9 10
    print(li4);//空
}
c++ 复制代码
#include <list>
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;

// 打印两个list的内容
void printLists(const list<int>& l1, const list<int>& l2)
{
    cout << "list1: ";
    // 使用copy算法和ostream_iterator将list1的内容输出到cout
    copy(l1.cbegin(), l1.cend(), ostream_iterator<int>(cout, " "));
    cout << endl << "list2: ";
    // 使用copy算法和ostream_iterator将list2的内容输出到cout
    copy(l2.cbegin(), l2.cend(), ostream_iterator<int>(cout, " "));
    cout << endl << endl;
}

int main()
{
    // 创建两个list对象
    list<int> list1, list2;

    // 向list1和list2中添加元素
    for (int i = 0; i < 6; ++i)
    {
        list1.push_back(i);  // 在list1的末尾添加元素
        list2.push_front(i); // 在list2的头部添加元素
    }

    // 打印list1和list2的内容
    printLists(list1, list2);

    // 在list2中找到值为3的元素,并将list1的所有元素移动到该位置之前
    list2.splice(find(list2.begin(), list2.end(), 3), list1);

    // 打印list1和list2的内容
    printLists(list1, list2);

    // 将list2的第一个元素移动到list2的末尾
    list2.splice(list2.end(), list2, list2.begin());

    // 对list2进行排序
    list2.sort();

    // 将list2的内容赋值给list1
    list1 = list2;

    // 移除list2中的重复元素
    list2.unique();

    // 打印list1和list2的内容
    printLists(list1, list2);

    // 将list2合并到list1中
    list1.merge(list2);

    // 打印list1和list2的内容
    printLists(list1, list2);

    return 0;
}

不支持随机访问

list 容器由于采用了双向迭代器,不支持随机访问,所以标准库的 merge(),

sort()等功能函数都不适用,list 单独实现了 merge(),sort()等函数。

c++ 复制代码
#include <iostream>
#include <list>
#include <iterator>
#include <algorithm>
using namespace std;

int main()
{
    // 创建一个list对象li,并初始化其内容为{1, 3, 5, 7, 9, 2, 4, 6, 8, 10}
    list<int> li = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};

    // 对li进行排序
    li.sort();

    // 遍历并输出排序后的li
    for (auto &i : li)
        cout << i << endl;

    // 创建另一个list对象li2,并初始化其内容为{11, 12, 15, 13, 14}
    list<int> li2 = {11, 12, 15, 13, 14};

    // 将li2合并到li中
    li.merge(li2);

    // 对合并后的li进行排序
    li.sort();

    // 遍历并输出排序后的li
    for (auto &i : li)
        cout << i << "\t";
    cout << endl;

    // 遍历并输出li2的内容
    for (auto &i : li2)
        cout << i << "\t";
    cout << endl;

    return 0;
}

高效的插入和删除

插入和删除是高效的,元素不需移动,内存仅是指针移动

c++ 复制代码
#include <iostream>
#include <list>
#include <iterator>
#include <algorithm>
using namespace std;

// 定义类A
class A
{
public:
    // 无参构造函数
    A()
    {
        cout << "无参构造函数 " << this << endl;
    }

    // 有参构造函数
    A(int i) : _data(i)
    {
        cout << "有参构造函数 " << this << endl;
    }

    // 拷贝构造函数
    A(const A & other)
    {
        cout << "拷贝构造 " << this << " from " << &other << endl;
    }

    // 拷贝赋值运算符
    A& operator=(const A & other)
    {
        cout << "拷贝赋值 " << this << " from " << &other << endl;
        return *this;
    }

    // 析构函数
    ~A()
    {
        cout << "析构函数 " << this << endl;
    }

private:
    int _data; // 私有成员变量
};

int main()
{
    // 创建一个存储A类型对象的list
    list<A> la;

    // 使用assign方法将list填充为10个临时A对象
    la.assign(10, A());

    // 删除list的第一个元素
    la.erase(la.begin());

    // 在list的开始位置插入一个新的临时A对象
    la.insert(la.begin(), A());

    return 0;
}

插入和删除不会使迭代器失效。 删除建议使用remove/remove_if

相关推荐
童先生12 分钟前
Go 项目中实现类似 Java Shiro 的权限控制中间件?
开发语言·go
lulu_gh_yu13 分钟前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
Re.不晚37 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
老秦包你会39 分钟前
Qt第三课 ----------容器类控件
开发语言·qt
凤枭香42 分钟前
Python OpenCV 傅里叶变换
开发语言·图像处理·python·opencv
ULTRA??1 小时前
C加加中的结构化绑定(解包,折叠展开)
开发语言·c++
远望清一色1 小时前
基于MATLAB的实现垃圾分类Matlab源码
开发语言·matlab
confiself1 小时前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
凌云行者1 小时前
OpenGL入门005——使用Shader类管理着色器
c++·cmake·opengl
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee