约瑟夫环问题简单练习

来源:互联网 发布:淘宝设计工作室 编辑:程序博客网 时间:2024/05/20 01:47

背景故事

约瑟夫环问题起源于一个犹太故事。约瑟夫环问题的大意如下:

  罗马人攻占了桥塔帕特,41个人藏在一个山洞中躲过了这场浩劫。这41个人中,包括历史学家Josephus(约瑟夫)和他的一个朋友。剩余的39个人为了表示不向罗马人屈服,决定集体自杀。大家制定了一个自杀方案,所有这41个人围成一个圆圈,由第一个人开始顺时针报数,每报数为3的人就立刻自杀,然后再由下一个人重新开始报数,仍然是每报数为3的人就立刻自杀……,直到所有的人都自杀身亡为止。

  约瑟夫和他的朋友并不想自杀,于是约瑟夫想到了一个计策,他们两个同样参与到自杀方案中,但是最后却躲过了自杀。请问,他们是怎么做到的?

问题描述

约瑟夫环:

  • 一群人沿圆桌坐成一个环(N)
  • 从某个编号开始报数(K)
  • 数到某个数(m)的时候,此人出列,下一个人重新报数
  • 一直循环,知道所有人出列,约瑟夫环结束

解决方案

这是一个典型的循环链表题目。我们需要创建一个循环链表,依照游戏规则,依次进行删除结点操作。直至链表为空,打印出的元素顺序即为出局顺序!


这里写图片描述

下面用C语言写出约瑟夫环问题的程序,创建链表,添加数据,依次删除结点操作,直到链表为空表,源代码如下:

#include <stdio.h>#include <stdlib.h>#define LEN sizeof(node)typedef struct Node {    int data;    struct Node *next;}node;//创建一个n个结点的链表node *CreateLink(int n) {    node *head, *pf, *pb;     //head:头结点    pf:当前位置的结点     pb:新建的结点    //创建n个结点——循环n次    int count = 0;    for (int i=0; i<n; i++) {           pb = (node *)malloc(sizeof(LEN));         //新建一个结点        //判断是否建立成功        if (pb == NULL) {                                   printf("Create Link failed\n");            return NULL;        }        pb->data = ++count;                  //为新建结点的数据成员赋值        //判断新建立的结点的位置,        if (0 == i) {            head = pb;                       //如果是第一个结点,则赋给head            pf = pb;                         //新建的第一个结点也就是当前结点        } else {            pf->next = pb;                   //新建的结点为当前结点的下一个结点        }        pb->next = NULL;                     //为新建结点的next指针赋值        pf = pb;                             //当前结点改为pb,为下一个结点创立做准备    }    pf->next = head;    return head;}int main(void) {    int sum = 41;    int flag = 3;    node *t, *h;      //h指向每次的起点                              //t指向要删除的点    h = CreateLink(sum);    while (h != h->next) {        for (int i=1; i<flag-1; i++) {            h = h->next;        }        t = h->next;//t为要删除的结点        h->next = t->next;        printf("%d ", t->data);//输出删除的数        h = t->next;//新一轮开始     }    printf("%d\n", h->data);    return 0;}
//修改版#include <stdio.h> #include <stdlib.h>typedef struct node {    int data;    struct node *next;}node;node *create(int n) {    node *head;    head = (node *)malloc(sizeof(node));    int i=1;    node *s,*p=head;    while (i<=n) {        s = (node*)malloc(sizeof(node));        s->data = i++;        p->next = s;        p = p->next;    }    p->next = head->next;    free(head);    return p->next;}int main(void) {    int i,n,m;    node  *newstart,*h,*t;    m=3;    n=10;    newstart=create(n);    h=newstart;    while(h!=h->next) {        for(i=1;i<m-1;i++) {            h=h->next;        }        t=h->next;        printf("%d ",h->next->data);        h->next=t->next;        h=t->next;        free(t);        t = NULL;    }    printf("%d\n", h->data);    return 0;}
0 0