C++ STL之list容器的基本操作

时间:2024-01-16 18:10:32

由于list和vector同属于序列式容器,有很多相同的地方,而上一篇中已经写了vector,所以这一篇着重写list和vector的不同之处和特有之处。

特别注意的地方:

(1)STL中迭代器容器中都要注意的地方(vector中已经提到):
1)任何时候同时使用两个迭代器产生的将会是一个前闭后开的区间(具体见插入和删除的例子)
2)begin()指向的是vec中的第0个元素,而end是指向最后一个元素的后面一个位置(不是最后一个元素)
3)迭代器的时效性,如果一个迭代器所指向的内容已经被删除,而后又使用该迭代器的话,会造成意想不到的后果

(2)list的迭代器是双向迭代器(只能++   --,没有偏移功能)而不是像vector那样的随机迭代器(和指针几乎一样的所有功能)

(3)list和vector的区别,本质区别:list是链式存储,vector在内存中是连续区别的,有本质区别而导致下面区别

1)list不支持随机访问(2)中已经说明,vector可以像数组那样使用平[]访问元素,而list是不可以的

2) list的插入和删除效率很高,所以list有push_front、pop_front、sort而vector中这些操作的效率太低了,所以STL中没有写这些功能

3)list的一些特有的函数remove、reverse、unique、splice、merge功能(这些连deque中都没有的)

下面就是区别于vector的功能的list操作

 #include<iostream>
#include<list>
using namespace std;
void print(list<int> link)
{
list<int> ::iterator it;
for(it=link.begin();it!=link.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
}
int main()
{
//链表的初始化是使用指针的,所以使用的是数组的地址
//特别注意:vector中已经注意到两个迭代器形成的区间是前闭后开的
int num[]={,,,,,,,,,};
list<int> link(&num[],&num[]+);
print(link); //特别注意list的迭代器是双向迭代器,而不是vector那样的随机迭代器,双向迭代器没有偏移能力,只能++ --,不能+5
/*例如,下面这两句就只能在随机迭代器中用,而不能再双向迭代器中用
list<int> ::iterator it=link.begin();
it=it+3;*/ //push操作,vector是在内存中是顺序存储的,如果往头部添加或者删除元素效率会非常的低,所以vector中并没有push_front,pop_front操作,
//但链表是链式存储的不用担心这个问题
link.push_front();
print(link); //链表的删除操作除了erase之外,还有一个romove。
//remove与erase不同,erase是删除指定位置的节点,而remove是删除指定值的节点
cout<<"删除第一个元素:"<<endl;
link.erase(link.begin());
print(link);
cout<<"删除值为6的所有元素"<<endl;
link.remove();
print(link); //排序,list中的排序有直接的函数而不需要使用algorithm里面的函数
cout<<"原来的数据:"<<endl;
print(link);
cout<<"sort之后的数据:"<<endl;
link.sort();
print(link); //反转reverse
cout<<"原来的数据:"<<endl;
print(link);
cout<<"reverse之后的数据:"<<endl;
link.reverse();
print(link); //unique功能去除链表中相邻的重复元素
int a[]={,,,,,,,,,};
list<int>a_unique(&a[],&a[]+);
cout<<"原来的数据:"<<endl;
print(a_unique);
a_unique.unique();
cout<<"unique之后的数据:"<<endl;
print(a_unique); //在指定list的迭代器位置上拼接另一个链表中另一个迭代器或者另一个迭代器指定的区间的数据
//splice
int a1[]={,,};
int a2[]={,,};
list<int>link1(&a1[],&a1[]+);
list<int>link2(&a2[],&a2[]+);
cout<<"原来的数据:"<<endl;
cout<<"link1:"<<endl;
print(link1);
cout<<"link2:"<<endl;
print(link2);
link1.splice(link1.begin(),link2,link2.begin());
cout<<"拼接后的数据:"<<endl;
cout<<"link1:"<<endl;
print(link1);
cout<<"link2:"<<endl;
print(link2); cout<<"原来的数据:"<<endl;
cout<<"link1:"<<endl;
print(link1);
cout<<"link2:"<<endl;
print(link2);
link1.splice(link1.end(),link2,link2.begin(),link2.end());
cout<<"拼接后的数据:"<<endl;
cout<<"link1:"<<endl;
print(link1);
cout<<"link2:"<<endl;
print(link2); //融合两个排序的list,融合的list依然是排序的
int b1[]={,,};
int b2[]={,,};
list<int>l1(&b1[],&b1[]+);
list<int>l2(&b2[],&b2[]+);
cout<<"原来的数据:"<<endl;
cout<<"l1:"<<endl;
print(l1);
cout<<"l2:"<<endl;
print(l2);
l1.merge(l2);
cout<<"融合后的数据"<<endl;
cout<<"l1:"<<endl;
print(l1);
cout<<"l2:"<<endl;
print(l2); //如果需要使用merge融合两个list,事先需要对两个list排序
//有些书中说融合两个未排序的list,融合的list也是未排序的
//很遗憾,在vs2010中这样运行会出错的,如下面这段代码,虽然编译通过,但是运行会出错
/*int c1[3]={1,4,4};
int c2[3]={6,3,5};
list<int>lc1(&c1[0],&c1[2]+1);
list<int>lc2(&c2[0],&c2[2]+1);
cout<<"原来的数据:"<<endl;
cout<<"lc1:"<<endl;
print(lc1);
cout<<"lc2:"<<endl;
print(lc2);
lc1.merge(lc2);
cout<<"融合后的数据"<<endl;
cout<<"lc1:"<<endl;
print(lc1);
cout<<"lc2:"<<endl;
print(lc2);*/
return ;
}

由于运行结果在一张截屏没法截下来了,所以就不贴结果了