STL(五)——list链表

一、链表

链表是一种数据结构。
链表有一个“头指针”变量,以head表示,只要有头指针就可以得到这条链表的所有信息。它不存储数据只存放一个地址,该地址指向下一个元素。
链表中每一个元素称为“结点”,每个结点都应包括两个部分:

  1. 数据域:用户需要用的实际数据
  2. 指针域:存放下一个结点的地址

head指向第一个元素,第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束,单链表示意图如下:
单链表

二、slist/list

slist/list是STL对于链表的一种实现。
slist:迭代器属于单向的Forward Iterator(可读写)。
list :迭代器属于双向的Bidirectional Iterator(可以双向读写)。
看起来slist的功能应该会不如list,但由于其单向链表的实现,其消耗的空间更小,某些操作更快。
这里重点介绍list,双向链表示意图如下:
在这里插入图片描述
1、list的构造函数

list<int>a{1,2,3}
list<int>a(n)    //声明一个n个元素的列表,每个元素都是0
list<int>a(n, m)  //声明一个n个元素的列表,每个元素都是m

2、push_back()和push_front()
插入一个元素到list中
push_back():从list的末端插入(尾***r>push_front():从list的头部插入。(头***r>调用list容器的成员函数begin():得到一个指向容器起始位置的iterator可以调用list容器的end()函数:得到list末端下一位置

3、clear()
清空list中的所有元素

4、front()和back(),pop_back()和pop_front()
front():获得list容器中的头部元素
back():获得list容器的最后一个元素
pop_back():删掉尾部第一个元素
pop_front():删掉头部第一个元素
链表为空时调用不会报错,故最好先调用empty()函数判断。

5、reverse()
可以实现list的逆置

6、insert()
在指定位置插入一个或多个元素

a.insert(a.begin(),100);  //在a的开始位置(即头部)插入100
a.insert(a.begin(),2, 100);   //在a的开始位置插入2个100

7、erase()
用迭代器遍历删除,执行后it会指向下一个元素。

list<int>::iterator it;
for(it = List.begin(); it != List.end() ; ) {
  it =  List.erase(it);  //it指向了下一个元素
}

三、例题

HDOJ-1276士兵队列训练问题

Problem Description
某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。

Input
本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过5000。

Output
共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。

Sample Input

2
20
40

Sample Output

1 7 19
1 19 37
#include<bits/stdc++.h>
using namespace std;
#define fio ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int main() {
    fio 
    int n, m;
    cin >> n;
    while (n--) {
      list<int> l;
      list<int>::iterator it;
      cin >> m;
      for (int i = 1; i <= m; i++)
        l.push_back(i);//注意插入链表操作的关键词
    int flag = 2, count;
    while (l.size() > 3) { 
      count = 1;//报数每次由1开始
      for (it = l.begin(); it != l.end(); ) {
        if (count++ % flag == 0) 
          it = l.erase(it);//执行后迭代器自动指向下一个元素,故需要“it=”
        else 
          it++;
      }
      flag == 2 ? flag = 3: flag = 2;//2、3交替轮流进行
    }
    for (it = l.begin(); it != l.end(); it++) {
      if (it != l.begin()) {
        cout << " ";
      }
      cout << *it; 
    }
    cout <<endl;
  }
}
全部评论

相关推荐

03-06 12:44
已编辑
吉林大学 Java
是个千人厂,没听过名字。1.&nbsp;做一个自我介绍。2.&nbsp;你这个项目和技术栈从哪里学的?有报辅导班嘛[答&nbsp;都是是自己网上学的,学校教的东西没用]3.&nbsp;我看了你放在github上的项目,前端也是你写的嘛[答&nbsp;AI写的,90%精力用于后端开发,前端单纯用于作为后端逻辑的可视化技术验证(骗你的其实后端也是AI写的)]4.&nbsp;好,你觉得这些技术栈研究得最深刻的是哪个[答&nbsp;八股压根没背到后面,昨晚背了MySQL就说MySQL]5.&nbsp;那讲一下MySQL的索引[答&nbsp;从B+树选型一路吟唱到联合索引,索引失效]6.&nbsp;联合索引ABC问题,AB走索引嘛,BC走索引嘛?BAC走索引嘛?A&nbsp;or&nbsp;B&nbsp;走索引嘛[走,不走,走,不走。面试官点头说可以]7.&nbsp;讲一下项目里Redission分布式锁实现8.&nbsp;Watchdog机制具体是怎么工作9.&nbsp;消息队列有考虑过Kafka嘛,怎么选型的10.&nbsp;你这个项目消息队列可能出现什么问题,怎么解决这个问题?[瞎扯没用的,被面试官引导答了视频处理可能产生消息堆积问题,然后开始吟唱]11.&nbsp;文件分片自己写的还是用的什么框架?上传进度的Redis数据结构?上传的视频有多大?小分片大小?12.&nbsp;项目里Redis会话记忆是啥意思?[面试官说不行,没人把这个全放Redis里[生气R]]13.&nbsp;那这和直接查数据库有什么区别[扯了Token成本和解决幻觉问题之类的,给面试官听笑了,我最后也没绷住]14.&nbsp;你平时是怎么使用AI&nbsp;coding的15.&nbsp;算法,给了我一个leedcode链接,一看做过了。然后换了一道三数之和,也做过了。然后面试官说算了,让我讲讲思路吧反问:1.有什么需要提高的地方2.介绍一下部门业务有哪些这个面试官真的感官非常非常好,问问题还疯狂引导,感觉不会也会了。找实习&nbsp;&nbsp;牛客AI配图神器#
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务