目录
简介
list是双向链表,有vector,deque的特征,而且效率高,缺点是,它不能像 array 和 vector 那样,通过位置直接访问元素。
如何需要对序列进行大量添加或删除元素的操作,而直接访问元素的需求却很少,这种情况建议使用 list 容器存储序列。
它有插入(前插,后插,中间插),删除(前删,后删,清空等),排序等功能。
而且,可以剔除连续相同元素,保留一个。
接下来,用一个程序将它的功能串起来。
代码/*
list
Author:YuBo
Date:2018/2/5
*/
//注意与vector deque的相同点与不同点
#include<iostream>
#include<list>
#include<algorithm>
using namespace std;
list<int> l;
list<int>::iterator it;
list<int>::reverse_iterator rit;
void menu()
{
cout<<"******1.插入 2.删除************"<<endl;
cout<<"******3.读取首元素 4.读取末元素******"<<endl;
cout<<"******5.排序 6.查找************"<<endl;
cout<<"******7.剔除连续重复元素 8.显示所有元素****"<<endl;
cout<<"******9.退出*****************************"<<endl;
}
void PUSH()/*注意与deque的不同,双向链表list的插入全部扩张*/
{
int i,j,place,n,N;
cout<<"******1.前插 2.后插 3.中间插入*****"<<endl;
cin>>j;
switch(j)
{
case 1:{//前面插入,扩张
cout<<"请输入你要输入的整数个数:"<<endl;
cin>>N;
cout<<"请输入"<<N<<"个整数:"<<endl;
for(i=0;i<N;i++)
{
cin>>n;
l.push_front(n);
}
}break;
case 2:{ //从后面插入,扩张
cout<<"请输入你要输入的整数个数:"<<endl;
cin>>N;
cout<<"请输入"<<N<<"个整数:"<<endl;
for(i=0;i<N;i++)
{
cin>>n;
l.push_back(n);
}
}break;
case 3:{//中间插,扩张,后移
cout<<"请输入你要插入的位置(首位置为0):"<<endl;
cin>>place;
cout<<"请输入你要插入的数值:"<<endl;
cin>>n;
it=l.begin();
while(place){it++;place--;} //注意只能++或--不能+n或-n
l.insert(it,n);
}break;
default:cout<<"输入错误!"<<endl;
}
}
void POP()
{
int i,j,place,N;
cout<<"******1.前删 2.后删 3.中间删 4.清空*****"<<endl;
cin>>j;
switch(j)
{
case 1:{
cout<<"请输入你要删除的整数个数:"<<endl;
cin>>N;
if(N>l.size())cout<<"里面没有这么多元素。。。"<<endl;
else{
for(i=0;i<N;i++)
{
l.pop_front();
}
}
}break;
case 2:{
cout<<"请输入你要删除的整数个数:"<<endl;
cin>>N;
if(N>l.size())cout<<"里面没有这么多元素。。。"<<endl;
else{
for(i=0;i<N;i++)
{
l.pop_back();
}
}
}break;
case 3:{
cout<<"请输入你要删除的位置(首位置为0):"<<endl;
cin>>place;
if(place<0||place>l.size())cout<<"位置超界。"<<endl;
else{
it=l.begin();
while(place)it++;
l.erase(it);
}
}break;
case 4:{
l.clear();
}break;
default:cout<<"输入错误!"<<endl;
}
}
void Getfront()
{
if(l.empty())cout<<"队已经空了!"<<endl;
else cout<<"队顶元素为:"<<l.front()<<endl;
}
void Getback()
{
if(l.empty())cout<<"队已经空了!"<<endl;
else cout<<"队尾元素为:"<<l.back()<<endl;
}
void Getsize()
{
cout<<"双端队列的大小为:"<<l.size()<<endl;
}
void Sort()
{
l.sort();//排序后前序遍历是升序,反向遍历是降序
}
void Find()
{
int n;
cout<<"请输入你要查找的数:"<<endl;
cin>>n;
it=find(l.begin(),l.end(),n);
if(it!=l.end())
{
int sum=0;
list<int>::iterator temp;
temp=l.begin();
while((*temp)!=(*it)){sum++;temp++;}
cout<<n<<"是第"<<sum<<"个数。"<<endl;
}
else
cout<<"没找到"<<endl;
}
void Unique()
{
l.unique();//重复元素保留一个
}
void Display()
{
int i;
cout<<"*******1.前向遍历 2.反向遍历******"<<endl;
cin>>i;
switch(i)
{
case 1:{
for(it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
}break;
case 2:{
for(rit=l.rbegin();rit!=l.rend();rit++)
{
cout<<*rit<<" ";
}
cout<<endl;
}break;
default:cout<<"输入错误!"<<endl;
}
}
int main()
{
int i;
while(1)
{
menu();
cout<<"请输入菜单号:"<<endl;
cin>>i;
if(i==9)break;
switch(i)
{
case 1:PUSH();break;
case 2:POP();break;
case 3:Getfront();break;
case 4:Getback();break;
case 5:Sort();break;
case 6:Find();break;
case 7:Unique();break;
case 8:Display();break;
default:cout<<"输入错误!";break;
}
}
return 0;
}
运行截图
------------------------------------------------2020-08-29更新-------------------------------------------------
常用函数常用成员函数 | 功能 |
---|---|
begin() | 返回指向容器中第一个元素的双向迭代器。 |
end() | 返回指向容器中最后一个元素的双向迭代器。 |
rbegin() | 返回指向最后一个元素的反向双向迭代器。 |
rend() | 返回指向第一个元素所在位置前一个位置的反向双向迭代器。 |
empty() | 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。 |
size() | 返回当前容器实际包含的元素个数。 |
front() | 返回第一个元素的引用。 |
back() | 返回最后一个元素的引用。 |
assign() | 用新元素替换容器中原有内容。 |
emplace_front() | 在容器头部生成一个元素。该函数和 push_front() 的功能相同,但效率更高。 |
push_front() | 在容器头部插入一个元素。 |
pop_front() | 删除容器头部的一个元素。 |
emplace_back() | 在容器尾部直接生成一个元素。该函数和 push_back() 的功能相同,但效率更高。 |
push_back() | 在容器尾部插入一个元素。 |
pop_back() | 删除容器尾部的一个元素。 |
emplace() | 在容器中的指定位置插入元素。该函数和 insert() 功能相同,但效率更高。 |
insert() | 在容器中的指定位置插入元素。 |
erase() | 删除容器中一个或某区域内的元素。 |
swap() | 交换两个容器中的元素,必须保证这两个容器中存储的元素类型是相同的。 |
clear() | 删除容器存储的所有元素。 |
void splice (iterator position, list& x); | position 为迭代器,用于指明插入位置;x 为另一个 list 容器。 此格式的 splice() 方法的功能是,将 x 容器中存储的所有元素全部移动当前 list 容器中 position 指明的位置处。 |
void splice (iterator position, list& x, iterator i); | position 为迭代器,用于指明插入位置;x 为另一个 list 容器;i 也是一个迭代器,用于指向 x 容器中某个元素。 此格式的 splice() 方法的功能是将 x 容器中 i 指向的元素移动到当前容器中 position 指明的位置处。 |
void splice (iterator position, list& x, iterator first, iterator last); | position 为迭代器,用于指明插入位置;x 为另一个 list 容器;first 和 last 都是迭代器,[fist,last) 用于指定 x 容器中的某个区域。 此格式的 splice() 方法的功能是将 x 容器 [first, last) 范围内所有的元素移动到当前容器 position 指明的位置处。 |
remove(val) | 删除容器中所有等于 val 的元素。 |
remove_if() | 删除容器中满足条件的元素。 |
unique() | 删除容器中相邻的重复元素,只保留一个。 |
merge() | 合并两个事先已排好序的 list 容器,并且合并之后的 list 容器依然是有序的。 |
sort() | 通过更改容器中元素的位置,将它们进行排序。 |
reverse() | 反转容器中元素的顺序。 |
list迭代器p1、p2,整数i
- p1[i]:不能通过下标访问 list 容器中指定位置处的元素。
- p1-=i、 p1+=i、 p1+i 、p1-i:双向迭代器 p1 不支持使用 -=、+=、+、- 运算符。
- p1<p2、 p1>p2、 p1<=p2、 p1>=p2:双向迭代器 p1、p2 不支持使用 <、 >、 <=、 >= 比较运算符。
注意:list 容器在进行插入insert())、接合(splice())等操作时,都不会造成原有的 list 迭代器失效,甚至进行删除操作时只有指向被删除元素的迭代器失效,其他迭代器不受任何影响。对于非 const 类型的 list 容器,迭代器不仅可以访问容器中的元素,也可以对指定元素的值进行修改。