闲话:当你了解了STL中的一两个容器之后,再去学习它另外的容器,就会发现它们的重合点非常多。

简述

如果你不想看这么多字,那么前两段就可以略过了。。。

  list 容器视线里双向链表的数据结构,数据元素通过链表指针连城逻辑意义上的线性表,这样,对链表的任一位置的元素进行插入、删除和查找都会是极快的。下图是list 采用的双向循环链表的结构示意图。
结构示意图
  list 的每个结点有三个域:前驱元素指针域、数据域、后继元素指针域。前驱元素指针域保存了前驱元素的首地址;数据域则存储本节点的数据;后继元素指针域则保存后继元素的首地址。list 的头结点的前驱元素指针域保存的是链表中尾元素的首地址,而list 的尾节点的后继元素指针域则保存了头结点的首地址,这样,就构成了一个双向的循环链。
  由于 list 对象的结点并不要求在一段连续的内存中,所以对于迭代器,只能通过“++”或“–”的操作将迭代器移动到后继/前驱节点处,而不能通过对迭代器进行+n或-n的操作(这句应该划重点)这是与vector不同的地方。

头文件

#include<list>

创建对象

 list<int> l;          //创建list对象
 list<int> l(10);      //创建一个有十个元素的list对象,每个元素默认为0
 list<int> l(10,4);    //创建一个有十个元素的list对象,每个元素都为

插入元素

  l.push_back(10);                   //尾部插入新元素
  l.push_front(11);                  //首部插入新元素
  list<int>::iterator it=l.begin();  //定义迭代器
  l.insert(++it,8);                  //在指定迭代器的位置插入新元素(迭代器只能--,++)

注:与 deque(双端队列)不同的是,以上三种插入方法都会是链表自动扩张。这是真正的插入新元素,而不是对旧元素的覆盖。

元素遍历

 list<int>::iterator it;             //迭代器遍历
 for(it=l.begin();it!=l.end();it++)
     cout<<*it<<" ";
     
 list<int>::reverse_iterator rit;   //反向迭代器遍历
 for(rit=l.rbegin();rit!=l.rend();rit++)

注:不可以用下标法随机访问、遍历。

元素删除

 l.pop_back();      //删除尾部元素
 l.pop_front();     //删除首部元素
 l.erase(it);       //删除迭代器指定元素
 l.clear();         //清空链表
 l.remove(4);       //删除所有值为4的元素
 l.unique();        //剔除连续重复元素,只保留一个

其他操作

l.sort();                          //以升序排列
it=find(l.begin(),l.end(),10);     //在迭代器区间内查找元素10,找到就返回该位置的迭代器,否则返回end()//包含在头文件algorithm里

附录unique()函数示例

#include<iostream>
#include<algorithm>
#include<list>
using namespace std;
int main()
{
    list<int> l;
    l.push_back(2);
    l.push_back(5);
    l.push_back(4);
    l.push_back(4);
    l.push_back(6);
    l.push_back(4);
    list<int>::iterator it;
    cout<<"剔除前:"<<endl;
    for(it=l.begin();it!=l.end();it++)
        cout<<*it<<" ";
    cout<<endl;
    l.unique();
    cout<<"剔除后:"<<endl;
    for(it=l.begin();it!=l.end();it++)
        cout<<*it<<" ";
    cout<<endl;
    return 0;
}
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐