一:问题描述
约瑟夫环问题是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列,他的下一个人又开始报数,数到m的那个人又出列,依次规律重复下去,圆桌周围的人全部出列。
二:算法原理
约瑟夫环运作如下:
1:一群人围坐在一起成环状
2:从某个编号开始报数(如:k)
3:数到某个数(如:m)的时候,此人出列,下一个人重新报数
4:一直循环,直到所有人出列,约瑟夫环出列
三:具体代码实现如下:(保留了最后一个编号)
#include<stdio.h> #include<stdlib.h> typedef struct Node{ int data; struct Node* next; }LNode,*LinkList; void Josephus(int n, int m, int k) { LinkList p = NULL, x = NULL, list = NULL; int i; for(i = 1; i <= n; i++) { p = (LNode*)malloc(sizeof(LNode));//向系统申请内存 if (p==NULL) {//确保指针使用前为非空指针,当p为空指针时结束程序 printf("分配失败!"); exit(1); } p->data = i;//编号 if(list == NULL) list = p; else x->next = p;//将x和p节点串起来 x = p;//x指针后移 } p->next = list;//建立一个循环链表 p = list;//p指针后移 for(i = 1; i < k; i++) { x = p; p = p->next; } //此时p指向第1个出发点 while(p->next != p) { for(i=1; i<m; i++) { x = p; p = p->next; } //p指向第m个结点,x指向第m-1个结点 x->next = p->next; //删除第m个结点 printf("%d号自杀\n", p->data); //输出一个结点编号 free(p); //释放被删除结点的空间 p = x->next; //p指向新的出发点 } printf("最后能生存下来的为%d号\n", p->data); //输出最后那个结点的编号 free(p); } int main() { int m,k,n; printf("请输入总人数:"); scanf("%d",&n); printf("请输入从第几人报数:"); scanf("%d",&k); printf("请输入间隔人数:"); scanf("%d",&m); Josephus(n, m, k); }