转载:点击打开链接
约瑟夫问题:
共n人参与游戏,从第K人开始报数,每次报m的人出列,找出最后剩下的一人的编号;
分析:
1.定义一个结构体,储存两类数据,分别为data和link;
2.设定两个节点,头结点pnode和当前节点curr,初始化链表,进行编号;
3.从编号1开始,数到第K个数将其删除;然后以K+1位为起点继续报数,~~~,数目不足就返回到编号1处继续接着报数,~~~,直至整个队列只剩下一人,输出编号。
形式一:
#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct node{
int data;
struct node *next;
node(){
data=0;
next=NULL;
}
}node,*listNode;
//n表示总人数,from表示开始人的标号,number表示选定的数字
void ysf(int n,int from,int number){
if(n<0||from<0||number<0) return;
listNode curr,pnode,prev;
pnode=new node();
pnode->data=1;
pnode->next=pnode;
curr=pnode;
for(int i=2;i<=n;i++){
listNode temp=new node();
temp->data=i;
temp->next=pnode;
curr->next=temp;
curr=temp;
}
while(from--){
prev=pnode;
//记录当前结点的前一结点
pnode=pnode->next;
}
while(n--){
//--i为true时循环执行prev=pnode;pnode=pnode->next;
for(int i=number;--i;prev=pnode,pnode=pnode->next);
prev->next=pnode->next;
printf("%d ",pnode->data);
free(pnode);
pnode=prev->next;
}
}
int main(){
ysf(10,0,3);
return 0;
}
运行结果:
形式二:
#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct node{
int data;
struct node *next;
}listNode;
typedef listNode *list;
list initial(int n,list R);
list deleteDeath(int n,int k,list R);
int main(){
list R;
int n,k;
cout << "总人数n=?";
cin >> n;
cout << "报数上限k=?";
cin >> k;
R=initial(n,R);
R=deleteDeath(n,k,R);
return 0;
}
list initial(int n,list R){
listNode *p,*q;
int i;
R=(listNode*)malloc(sizeof(listNode));
q=R;
for(int i=1;i<=n;i++){
p=(listNode*)malloc(sizeof(listNode));
p->data=i;
q->next=p;
q=p;
}
p->next=R->next;
return R;
}
list deleteDeath(int n,int k,list R){
int i,j;
listNode *p,*q;
p=R;
for(int i=1;i<=n;i++){
for(int j=1;j<=k-1;j++){
p=p->next;
}
q=p->next;
p->next=q->next;
printf("%4d ",q->data);
free(q);
R=p;//下次循环的起点
}
printf("\n");
return R;
}