约瑟夫环

 是一个数学的应用问题:

  已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。

  例如:n = 9, k = 1, m = 5

  【解答】

  出局人的顺序为5, 1, 7, 4, 3, 6, 9, 2, 8。

C语言实现:

  #include<stdio.h>
typedef struct
{
 int num;
 int secret;
 struct node *next;

}node,*linklist;

 


/* 创建链表    */
void creat(linklist head,int n)
{
  node *s,*p;
  int i,x;
  p=head;
  for(i=1;i<=n;i++)
  {
    s=(node *)malloc(sizeof(node));      /*  建立下一个结点,由s指向它*/
    s->num=i;
    printf("请输入第%d 个人的密码",i);
    scanf("%d",&x);
    s->secret=x;
    p->next=s;                               /* s 链接到前面的结点 */
    p=s;
  }
  p->next=head;                              /*建立成循环的链表      */

}

/*删除函数*/

void delete(node *p)                       /*删除p指向的下一个结点*/
{
  node *q=p->next;
  p->next=p->next->next;
  free(q);
}

 

/*判断链表是否为空*/
int empty(node *head)
{
  if(head->next==head)
     return 0;               /* 为空   */
   else
     return 1;               /* 不为空   */

}


/* 链表的初始化*/
void initiate(linklist *head)
{
  *head=(node *)malloc(sizeof(node));
  (*head)->next=NULL;

}

 

/*约瑟夫环 */
void   ring(linklist head,int m)
{
   node *pre,*s;
   int i;
   pre=head;                              /*pre是s的前驱*/
   s=head->next;
   while(empty(head)==1)                 /*判断链表是否为空*/
   {
      for(i=1;i<m;i++)
      {
        pre=s;
        s=s->next;
        if(s==head)                     /*  要跳过头结点*/
         {
           pre=s;
           s=s->next;
         }
       }


    printf("被叫到的序号是%d   ",s->num);
    printf("被叫到的密码是%d\n",s->secret);
    m=s->secret;
    s=s->next;
      if(s==head)
         s=s->next;
     delete(pre);
  }
}

 

void main(void)
{
  int n,m;
  linklist head;
  printf("请输入总人数");
  scanf("%d",&n);
  printf("请输入初始值");
  scanf("%d",&m);

  initiate(&head);
  creat(head,n);
  ring(head,m);

  getch();

 }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值