STL—list(双向链表)详解
闲话:当你了解了STL中的一两个容器之后,再去学习它另外的容器,就会发现它们的重合点非常多。简述如果你不想看这么多字,那么前两段就可以略过了。。。 list 容器视线里双向链表的数据结构,数据元素通过链表指针连城逻辑意义上的线性表,这样,对链表的任一位置的元素进行插入、删除和查找都会是极快的。下图是list 采用的双向循环链表的结构示意图。 list 的每个结点有三个域:前驱元素指针域...
闲话:当你了解了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;
}
更多推荐
所有评论(0)