C++复习(十一):STL库之list

8 篇文章 0 订阅

之前list这个容器漏写了,后来很长时间没写博客,今天有时间,补一下。

list底层是双向循环链表,因此不支持随机访问,但对于插入和删除能做到O(1)的复杂度,且插入和删除不会使迭代器失效。(PS:vector的插入删除应该会使迭代器失效;deque只有在删除头尾元素时使该元素对应的迭代器失效,其他的插入删除情况会使所有迭代器失效)

1、构造和赋值

#include<iostream>
using namespace std;

//构造
list<int> L1;                //创建一个空的list
list<int> L2(10, 0);         //创建一个大小为10,值都为0的list
list<int> L3(L2);            //创建一个和L2一样的list
vector<int> v1 = {1, 2, 3, 4, 5};
list<int> L4(L2.begin(), L2.end());    //通过迭代器构造list。有随机访问迭代器的才有加减法,没有随机访问迭代器的只有++或--操作。
list<int> L5(v1.begin(),v1.begin()+3);   //通过迭代器构造list,L5应为{1,2,3}
int num[] = {1, 2, 3, 4, 5};
list<int> L6(num, num + size(num));    //通过数组地址构造list。
list<int> L7 ={1,2,3,4,5};             //直接对list进行赋值。

//赋值,要先获得该节点对应的迭代器。
list<int>::iterator it = L5.begin();    //获取迭代器
*it = 5;                                //修改对应的值,现在L5应为{5,2,3}

2、大小、容量

L5.size();        //返回L5中元素的个数,即L5的大小,应为3。STL的SGI版本的实现中这个函数是O(n)的时间复杂度,有点难顶。
L5.max_size();    //返回容器所能容纳的最大元素数目。这是系统或者库所实施的限制,但是容器不一定保证能达到该大小,有可能在还未达到该大小的时候,就已经无法继续分配任何的空间了。这个函数似乎没有什么卵用。
L5.resize(5);     //重新指定容器中有效的元素个数。
/*
对于大小为n的容器,当调用L5.resize(m)后,有两种情况:
1.若 m < n ,则只保存容器前m个元素。
2.若m > n ,则容器之前储存的n个元素不变,不足m的部分补0。
这里调用后L5应为{5,2,3,0,0}
*/
L5.empty();       //返回L5是否为空,如果为空则返回True,否则返回False。这里应返回False。

3、插入和删除

//插入
list<int> L8;
L8.push_front(4);                // 头部增加元素,应为{4}
L8.push_back(5);                 // 末尾添加元素,应为{4,5}
L8.insert(++L8.begin(), 2);      // 任意位置插入一个元素,应为{4,2,5}
L8.insert(L8.begin(), 3, 9);     // 任意位置插入n个相同元素,应为{9,9,9,4,2,5}
vector<int> v2={1,2,3};
L8.insert(++L8.begin(), v2.begin(), v2.begin()+2);    // 插入另一个容器的数据,应为{9,1,2,9,9,4,2,5}

//删除
L8.pop_front();                            // 头部删除元素,应为{1,2,9,9,4,2,5}
L8.pop_back();	                           // 末尾删除元素,应为{1,2,9,9,4,2}
L8.erase(++L8.begin());                    // 任意位置删除一个元素,应为{1,9,9,4,2}
L8.erase(L8.begin(), ++L8.begin());	   // 删除两个迭代器之间的元素,应为{9,9,4,2}
L8.clear();	                           // 清空所有元素,应为{}

4、取值和遍历

L8 = { 9,1,2,9,9,4,2,5 };

// 获取最后一个元素和第一个元素,必须在L8.empty()!=0时调用,否则此函数将创建未定义的行为。
L8.back();
L8.front();

//正向遍历
for (list<int>::iterator it = L8.begin(); it != L8.end(); ++it)    //list<int>::iterator可以用auto代替
	cout << *it << " "; // 输出为:9 1 2 9 9 4 2 5 
cout << endl;

//反向遍历
for (list<int>::reverse_iterator it = L8.rbegin(); it != L8.rend(); ++it)    //list<int>::reverse_iterator可以用auto代替
	cout << *it << " "; // 输出为:5 2 4 9 9 2 1 9 
cout << endl;

5、查找、排序和反转

#include<algorithm>

//查找
//list<T>没有专门的find成员函数
auto it=find(L8.begin(), L8.end(), 2);    //只能通过algorithm的find函数来找到同值的迭代器
cout<<*it<<endl;                          //输出2
cout<<*(++it)<<endl;                      //输出9

//反转
reverse(L8.begin(), L8.end());            //应为{5,2,4,9,9,2,1,9}

//排序
//algorithm的sort函数不适用于list,因为sort函数要求容器有随机访问迭代器。
L8.sort();                                //只能通过list的sort成员函数来排序。默认从低到高,应为{1,2,2,4,5,9,9,9}
L8.sort(greater<int>());                  //从高到低,应为{9,9,9,5,4,2,2,1}

auto cmp1 = [](const int a, const int b) {return (a > b); };
L8.sort(cmp1);                             //用自定义比较器(lambda表达式)进行排序,应为{9,9,9,5,4,2,2,1}

class my_less{
    public:
    bool operator () (const int a, const int b){
        return a < b;
    }
};
L8.sort(my_less());                        //用自定义比较器(类)进行排序,应为{1,2,2,4,5,9,9,9}

6、两个有序list的合并(居然提供了这种成员函数)

list<int> L9 = { 14, 2, 4, 6 };
list<int> L10 = { 1, 7, 10, -2 };

//默认的merge成员函数只能合并两个升序序列
L9.sort();     //L9应为{2,4,6,14}
L10.sort();    //L10应为{-2,1,7,10}
L9.merge(L10);                //L9应为{-2,1,2,4,6,7,10,14},L10应为{}。
cout << boolalpha << L10.empty() << endl;    //输出true

L9 = { 14, 2, 4, 6 };
L10 = { 1, 7, 10, -2 };
//自定义比较器的merge成员函数
//auto cmp1 = [](const int a, const int b) {return (a > b); };
L9.sort (cmp1);     //L9应为{14,6,4,2}
L10.sort (cmp1);    //L10应为{10,7,1,-2}
L9.merge (L10, cmp1);    //L9应为{14,10,7,6,4,2,1,-2},L10应为{}。

7、将另一个list的元素移到当前list的指定位置的前面(居然还提供了这种成员函数)

list<int> L11 = { 14, 2, 4, 6 };
list<int> L12 = { 1, 7, 10, -2 };

L11.splice(++L11.begin(), L12, ++L12.begin());    //把7移动到了2前面,L11应为{14,7,2,4,6},L12应为{1,10,-2}。
L11.splice(++L11.begin(), L12, ++L12.begin(), L12.end());    //把10,-2移动到了7前面,L11应为{14,10,-2,7,2,4,6},L12应为{1}。
L11.splice(++L11.begin(), L12);    //把1移动到了10前面,L11应为{14,1,10,-2,7,2,4,6},L12应为{}。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值