单向循环链表(约瑟夫问题)代码:
#include<iostream>
using namespace std;
struct node
{
int data;
node *next;
};
int n,m;
node *head,*tail,*p;
int main()
{
int i,j,k,l;
cin>>n>>m;
head=new node;
head->data=1;
head->next=NULL;
tail=head; //将头尾结点都指向1
for(i=2;i<=n;i++)
{
p=new node;
p->data=i;
p->next=NULL;
tail->next=p;
tail=p;
} //建立链表
tail->next=head;
tail=head; //单链表头尾相连,成为循环单链表
for(i=1;i<=n;i++)
{
for(j=1;j<=m-2;j++)
tail=tail->next;
cout<<tail->next->data<<" ";
tail->next=tail->next->next;
tail=tail->next;
}
return 0;
}
双向循环链表(约瑟夫问题)代码:
#include<cstdio>
using namespace std;
struct node
{
int data; //记录这个结点对应的编号
node *next,*pre; //next 指向结点的后继, pre指向结点的先驱
}*head,*tail,*p; //head表示头结点 tail表示尾结点
int n,m;
int main()
{
scanf("%d%d",&n,&m);
head=new node;
head->data=1;
head->next=head->pre=NULL;
tail=head; //先建立编号为1的结点,头指针和尾指针都指向它
for(int i=2;i<=n;++i)
{
p=new node;
p->data=i; //建立编号为i的结点
tail->next=p; //将p指向的结点 插入到tail指向的结点 后面
p->pre=tail;
p->next=NULL;
tail=p; //将tail更新为p,下次就插入在它的后面
}
head->pre=tail;
tail->next=head; //因为是循环列表,所以头尾相连
p=head;
for(int i=1;i<=n;++i) //需要按照顺序删除n-1 个结点
{
for(int j=1;j<m;++j) //找到需要删除的结点
p=p->next;
printf("%d ",p->data); //输出值
p->next->pre=p->pre; //删除结点
p->pre->next=p->next;
p=p->next; //从下一个重新报数
}
}
数组模拟链表(约瑟夫问题)代码:
#include<iostream>
using namespace std;
const int N=100;
int a[N+1]; //a[i]表示第i号人的下一人的编号
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<n;i++) //建立数组模拟链表
{
a[i]=i+1;
}
a[n]=1; //建立数组模拟循环链表 第n人指向1,形成一个环
int pre=n; // 前一人
int cur=1; // 当前人
for (int p=0;p<n;p++) //n个人均出队为止
{
for(int k=1;k<m;k++) //报数计数器加一
{
pre=cur; //前一人变成当前人
cur=a[pre];//当前人变成下一人
}
cout<<cur<<" "; //数到m此人出队
a[pre] =a[cur]; //前一个人的下一个人变成当前人的下一人
a[cur] =0; //当前人的下一人变成0
cur=a[pre] ; //当前人变成当前的下一个人
}
return 0;
}
一维数组(约瑟夫问题)代码:
#include<iostream>
using namespace std;
const int N=100;
bool a[N+1]; //初始为false
int main()
{
int n,m,f=0,t=0,s=0;//f出圈的人数,t圈中位置编号,s为计数器
cin>>n>>m;
do
{
t++;//枚举圈中每个人
if(t==n+1) //数组模拟环状
{
t=1;
}
if(!a[t]) //t的位置有人报数
{
s++;
}
if(s==m) //当前报的数是m
{
s=0; //计数器清0
cout<<t<<" " ; //输出出圈人的编号
a[t] =true; //标记已经出局
f++; //出局的人增加一个
}
}while(f!=n); //全部出局为止
return 0;
}