STL list的操作:
约瑟夫问题
1.使用STL中的list需要引用头文件#include<list>或者#include<bits/stdc++.h>
//想要应用STL中的list的,可以引用头文件#include<list>或直接用#include<bits/stdc++.h>
#include<list>
using namespace std;
int n,m;
2.STL库中的list的定义方法:list<数据类型>表名
//定义一个用于存int数据的链表:list<数据类型>链表名:list<int>node;
list<int>node;
int main(){
scanf("%d%d",&n,&m);
3.通过push_back(x)函数将对应的值插入到链表中,注意此时形成的链表不是首尾相连的
//通过push_back(数据),将需要插入表中的节点的值存入表中
for(int i=1;i<=n;i++){
node.push_back(i);
}
3.由于在STL中的list没有下标引用的方式,所以需要设置一个迭代器:
list<数据类型>::iterator 迭代器名
//由于对于STL中的list没有下标引用,所以需要设置迭代器:
//list<int>(链表的类型)::iterator it(迭代器+名字)
4.获得链表的首地址:链表名.begin()
//链表名.begin():获得链表的首地址
list<int>::iterator it=node.begin();
5.判断链表中的节点的个数:链表名.size()
//只要链表里的节点(用size()函数)的个数大于1,就继续游戏
while(node.size()>1){
for(int i=1;i<m;i++){
it++;
6.STL中的list实际上是线性存储,需要通过迭代器实现看似的首尾相连:
当it=node.end()时,就将it=node.begin(),就实现了首尾相连。
//注意由于对于STl中的链表实际上只是一个线性的存储,所以需要通过迭代器实现链表的看似的首位相连
7.通过链表名.end()就可以获得链表的最后一个节点的后一个位置
//list.end()链表的最后一个节点的后一位
//注意进行特判:如果发现迭代的时候到达了链表的结尾,则进行循环
if(it==node.end()){
it=node.begin();
}
}
8.输出某个节点的信息:通过间接引用符*: *地址
//输出对应节点的值:*地址
printf("%d ",*it);
9.STL中的list中的迭代器是不允许跨越式迭代的,只能进行相邻的节点之间的迭代
//注意STL中的list的迭代器是不支持跨越式的迭代的,只能it++,--it等相邻的迭代
list<int>::iterator next=++it;
10.特别注意在用STL删除某个节点的时候,用erase(节点),还有如果想要获得删除的节点的后一个节点的地址,next=++it,那么如果先将it删除,那么就释放了it的那个节点的空间,也就是表示指向那个节点的指针也就成游离状态了,那么就会出错,所以需要先获得需要删除的节点的后一个节点的地址时,需要先获得地址,再将点删除
特别注意:需要再删除第m个节点前先将下一轮进行报数的next获得,同理判断是否需要循环回表头
//之后再删除第m个节点,将迭代器进行更新it=next,否则如果先删除第m个节点,则释放了该节点的空间、
//则指针it游离了,所以不能获得正确的next
if(next==node.end()){
next=node.begin();
}
node.erase(--it);
it=next;
}
11.注意在迭代的过程中需要注意进行判断是否到达了end(),如果到达了end(),就将迭代器的值更新成begin()
if(next==nodes.end()){
next=nodes.begin();
12.删除节点的方法:调用erase函数将对应的节点删除,即释放了空间
在删除节点之前注意判断是否需要获得删除的节点的下一个节点的地址,如果需要,就先获得下一个节点的地址,再将对应的节点删除
nodes.erase(--it);
it=next;
}
//输出最后一个节点对应的编号
printf("%d",*it);
return 0;
}
printf("%d",*it);
return 0;
}