STL序列式容器之list

一、概述

list使用一个双向链表来管理数据。使用list必须含入头文件<list>,其型别定义如下:

namespace std{
    template <class T,
              class Allocator = allocator<T> >
    class list;
}

list不支持随机存取,所以既不提供下标操作符,也不提供at()。list相较于vector的好处是每次插入或者删除一个元素,就配置或者释放一个元素空间。对于任何位置的元素插入或元素移除,list永远是常数时间。

二、list内部结构

list本身和list节点是不同的结构,需要分开设计,STL list节点结构如下:

template <class T>
struct __list_node {
    typedef void* void_pointer;
    void_pointer prev;
    void_pointer next;
}

SGI list不仅是一个双向链表,而且还是一个环状双向链表,结构图如下
这里写图片描述

三、list的操作函数

1. 生成、复制和销毁

操作效果
list<Elem> c产生一个存放Elem类型元素的空list
list<Elem> c1(c2)产生一个与c2同型的list,每个元素都被复制
list<Elem> c(n)产生一个含有n个元素,以default构造函数产生元素的list
list<Elem> c(n,elem)产生一个含有n个elem元素的list
list<Elem> c(beg,end)产生一个以区间[beg,end]内元素为初值的list
c.~list<Elem>()销毁所有元素,释放内存


2. 非变动性操作

操作效果
c.size()返回元素个数。
c.empty()判断容器大小是否为0。
c.max_size()返回可容纳元素最大数量
c1 == c2判断c1是否等于c2
c1 != c2判断c1是否不等于c2
c1 < c2判断c1是否小于c2
c1 > c2判断c1是否大于c2
c1 <= c2判断c1是否小于等于c2
c1 >= c2判断c1是否大于等于c2
c.front()返回第一个元素,不检查元素是否存在
c.back()返回最后一个元素,不检查元素是否存在
c.begin()返回一个随机存取迭代器,指向第一元素
c.end()返回一个随机存取迭代器,指向最后一个元素的下一位置
c.rbegin()返回一个逆向迭代器,指向逆向迭代时的第一个元素
c.rend()返回一个逆向迭代器,指向逆向迭代时最后元素的下一位置


3. 赋值操作

操作效果
c1 = c2将c2的全部元素赋值给c1。
c.assign(n,elem)将elem的n个拷贝赋值给c。
c.assign(beg,end)将区间[beg,end]的元素赋值给c
c1.swap(c2)将c1和c2元素互换
swap(c1,c2)同上,此为全局函数


4. 元素存取操作

操作效果
c.front()返回c的第一个元素,不检查元素存在与否
c.back()返回c的最后一个元素,不检查元素存在与否


5. 迭代器函数
list迭代器不支持随机存取,这些迭代器只是双向迭代器。

操作效果
c.begin()返回一个双向迭代器,指向第一个元素
c.end()返回一个双迭代器,指向最后一个元素的下一位置
c.rbegin()返回一个逆向迭代器,指向逆向迭代的第一个元素
c.rend()返回一个逆向迭代器,指向逆向迭代的最后元素的下一位置


6. 元素的安插和移除

操作效果
c.insert(pos,elem)在pos位置插入一个elem副本,返回新元素的位置
c.insert(pos,n,elem)在pos位置插入n个elem副本,无返回值
c.insert(pos,beg,end)在pos位置插入区间[beg,end]内的元素,无返回值
c.push_back(elem)在尾部添加一个elem的副本
c.pop_back()移除最后一个元素,不回传
c.push_front(elem)在头部插入一个elem副本
c.pop_front()移除头部元素,不回传
c.remove(val)移除所有值为val的元素
c.remove_if(op)移除所有造成op(elem)结果为true的元素
c.erase(pos)移除pos位置所指元素,返回下一元素的位置
c.erase(beg,end)移除区间[beg,end]内的元素,返回下一元素的位置
c.resize(num)将大小改为num。如果size增长了,新增大小以default构造函数产生出来
c.resize(num,elem)将大小改为num。如果size增长了,新增大小以elem副本产生出来
c.clear()移除所有元素,将容器清空



7. 特殊变动性操作

操作效果
c.unique()如果存在若干相邻而数值相等的元素,则移除重复元素,只留下一个
c.unique(op)如果存在若干个相邻元素都使op()的结果为true,则移除重复元素,只留下一个
c.splice(pos,c2)将c2内的所有元素转移到c1内、迭代器pos之前
c.splice(pos,c2,c2pos)将c2内的c2pos所指元素转移到c1内的pos所指的位置上,c1和c2可以相同
c.splice(pos,c2,c2beg,c2end)将c2内的[c2beg,c2end]区间所有元素转移到c1内的pos之前
c.sort()以operator<为准则对所有元素排序
c.sort(op)以op()为准则对所有元素排序
c.merge(c2)假设c1和c2内的元素已序,将c2内的全部元素转移到c1,保证合并后的list仍然有序
c.merge(c2,op)假设c1和c2内的元素按照op()已序,将c2内的全部元素转移到c1,保证合并后的list仍然在op()准则下有序
c.reverse()将所有元素反序


8. 异常处理
所有STL标准容器中,list对于异常安全性提供了最佳支持。

操作保证
push_back()如果不成功,就没有任何作用
push_front()如果不成功,就没有任何作用
insert()如果不成功,就没有任何作用
pop_back()不抛出异常
pop_front()不抛出异常
erase()不抛出异常
clear()不抛出异常
resize()如果不成功,就没有任何作用
remove()只要元素比较操作不抛出异常,就不抛出异常
remove_if()只要判断式不抛出异常,就不抛出异常
unique()只要元素比较操作不抛出异常,就不抛出异常
splice()不抛出异常
merge()只要元素比较时不抛出异常,保证“要么不成功,要么没有任何作用”
reverse()不抛出异常
swap()不抛出异常

四、程序示例

list的使用示例

//example of list
#include <iostream>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;

void printLists(const list<int>& l1, const list<int>& l2)
{
    cout << "list1: ";
    copy(l1.begin(), l1.end(), ostream_iterator<int>(cout, " "));
    cout << endl << "list2: ";
    copy(l2.begin(), l2.end(), ostream_iterator<int>(cout, " "));
    cout << endl << endl;
}
int main()
{
    list<int> l1, l2;

    for (int i = 0; i < 6; ++i){
        l1.push_back(i);
        l2.push_front(i);
    }
    printLists(l1, l2);

    l2.splice(find(l2.begin(), l2.end(), 3), l1);
    printLists(l1, l2);

    l2.splice(l2.end(), l2, l2.begin());
    printLists(l1, l2);

    l2.sort();
    l1 = l2;

    l2.unique();
    printLists(l1, l2);

    l1.merge(l2);
    printLists(l1, l2);

    l1.reverse();
    printLists(l1,l2);

    l1.sort();
    printLists(l1,l2);
    return 0;
}

输出结果:
这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值