约瑟夫(Josephus)环问题:编号为1,2,3,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一人开始重新从1报数,如此下去,直到所有人全部出列为止。
建立n个人的单循环链表存储结构,运行结束后,输出依次出队的人的序号。
#include <stdio.h>
#include <stdlib.h>
#include "malloc.h"
typedef struct Node{ //节点
struct Node *next;
int data;
}Node;
typedef struct List{ //循环链表存储结构
Node *front;
Node *rear;
int length;
}List;
List* Init(){
List* L = (List*)malloc(sizeof(List));
L->front = NULL;
L->rear = NULL;
L->length = 0;
}
void insert(List *L, Node *e){
if(L->length == 0){
L->front = e;
L->rear = e;
}else{
L->rear->next = e;
L->rear = e;
}
L->rear->next = L->front;
L->length++;
}
void display(List *L){
Node *p = L->front;
int i = 1;
for( ; i <= L->length; i++){
printf("The out is %d\n", p->data);
p = p->next;
}
}
int main()
{
int N = 30; //人数
int M = 3; //报数上限
List *L = Init();
int i = 1;
for(; i <= N; i++){
Node *e = (Node*)malloc(sizeof(Node));
e->data = i;
insert(L, e);
}
Node *p = L->rear;
Node *q = NULL;
int cnt = 1;
int REST = L->length;
while(REST > 0){
for(cnt = 1; cnt < M; cnt++){
p = p->next;
}
q = p->next;
printf("The out is %d\n", q->data);
p->next = p->next->next;
REST--;
}
return 0;
}