提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
引言
本小节我们来学习链表list相关知识点,以下是我的学习笔记,供给大家参考。
本章概括
第一章 STL和基本数据结构
章节 | 内容 |
---|---|
1.1 | 容器 vector |
1.2 | 队列 queue |
1.3 | 栈 stack |
1.4 | 链表 list |
1.5 | set |
1.6 | map |
1.4.1 list
1.介绍
- STL的list是数据结构的双向链表,它的内存空间可以是不连续的,通过指针来进行数据的访问,它可以高效率地在任意地方删除和插入,插入和删除操作是常数时间的。
- list和vector的优缺点正好相反,它们的应用场景不同。
(1)vector:插入和删除操作少,随机访问元素频率。
(2)list:插入和删除频繁,随机访问较少。
2.概念
- 链表是由一系列的结点组成,结点包含两个域,一个数据域,一个指针域。
1.链表内存是不连续的,添加元素和删除元素,它的时间复杂度都是常数项,不需要移动元素,比数组添加删除元素效率更高;
2.链表只有在需要的时候才分配内存。
3.链表需要额外的空间保存结点(前驱和后继)关系。
3.常见操作
功能 | 例子 | 说明 |
---|---|---|
定义 | list< int >a | 定义一个int类型的链表 |
在尾部插入元素 | a.push_back(x) | 在容器尾部插入一个元素 |
删除最后一个元素 | a.pop_back() | 删除容器中最后一个元素 |
在开头插入一个元素 | a.push_front(x) | 在容器开头插入一个元素 |
删除开头的元素 | a.pop_front() | 删除开头的元素 |
尾部插入 | a.push_back(i); | 在尾部插入i |
删除尾部 | a.pop_back(); | 删除尾部元素 |
插入 | a.insert(pos,n,elem) | 在pos位置插入n个elem元素 |
插入 | a.insert(pos,beg,end) | 在pos位置插入[beg,end)区间的数据,无返回值 |
清空 | a.clear(); | 清空所有数据 |
删除区间 | a.erase(beg,end) | 删除[beg,end)区间的数据,返回下一个数据的位置 |
删除指定元素 | a.remove(elem) | 删除容器中锁头与elem值相匹配的元素 |
元素个数 | a.size() | 返回容器中元素的个数 |
判断是否为空 | a.empty() | 判断容器是否为空 |
重置容器大小 | a.resize() | 重新指定容器长度 |
4.代码讲解
运用
#include<iostream>
#include<list>
using namespace std;
int main(){
//定义:
list<int>mlist1;
list<int>mlist2(10,7);//定义10个数值为7的链表
list<int>mlist3(mlist2);//拷贝mlist2
list<int>mlist4(mlist2.begin(),mlist2.end());//拷贝mlist2
//遍历
for(list<int>::iterator it = mlist4.begin();it != mlist4.end();it++)
cout<<*it<<" ";
cout<<endl;
//输出结果为:7 7 7 7 7 7 7 7 7 7 7
//插入
mlist1.push_back(7);//在容器尾部插入7
mlist1.push_front(77);//在容器开头插入77
mlist1.insert(mlist1.begin(),777);//在容器开头插入777
mlist1.insert(mlist1.end(),7777);//在容器结尾插入7777
list<int>::iterator it = mlist1.begin();
it++;
it++;
mlist1.insert(it,500);//在第二个元素后插入500
for(list<int>::iterator it = mlist1.begin();it != mlist1.end();it++)
cout<<*it<<" ";
cout<<endl; //遍历容器mlist1
//输出结果为 777 77 500 7 7777
//删除
mlist1.pop_back();//删除结尾元素
mlist1.pop_front();//删除开头元素
for(list<int>::iterator it = mlist1.begin();it != mlist1.end();it++)
cout<<*it<<" ";
cout<<endl; //遍历容器mlist1
//输出结果为77 500 7
mlist1.erase(mlist1.begin(),mlist1.end());//和mlist1.clear()效果一样,都是删除所有元素
return 0;
}
1.4.2例题
-
problem:
某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。 -
input
本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过5000。例如:
2
20
40 -
output
共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。
例如:
1 7 19
1 19 37
#include<iostream>
#include<list>
#include<string>
using namespace std;
int main(){
int t,n;
cin>>t;
while(t--)
{
cin>>n;
int k = 2;
list<int>mylist;//创建
list<int>::iterator it;
for(int i = 1;i <= k;i++)
{
mylist.push_back(i);//赋值
}
while(mylist.size()>3)
{
int num = 1;
for(it = mylist.begin();it!=mylist.end();)
{
if(num++ % k == 0)
it = mylist.erase(it);
else
it++;
}
k == 2?k=3:k=2;
}
for(it = mylist.begin();it!=mylist.end();it++)
{
if(it!=mylist.begin())
cout<<" ";
cout<<*it;
}
cout<<endl;
}
return 0;
}
下一节我们将对set进行详解,请大家持续关注