约瑟夫循环-链表

链表之报数问题

描述

有n个人围成一圈,顺序从1开始排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。建议用循环链表实现。

链表节点结构体:

typedef struct Node

{

int num;

struct Node* next;

};

输入

只有一个正整数n,(其中n的范围n>=3,n<=1000)。

输出

输出最后留下的人是原来的第几号。

请注意行尾输出换行。

输入样例 1 

10

输出样例 1

4

输入样例 2 

50

输出样例 2

11

算法概要:定义环形链表(双向),每当数到3后,将这一节点从链表中去除。

                  当节点的下一节点等于其自身时,只剩下该节点,退出循环,即找到了最后一人。

具体算法呈现如下:

#include<stdio.h>
#include<stdlib.h>

  struct node{
       int num;
       struct node *next;
       struct node *previous;
  };
  
  struct node * create(int a)
  {  struct node *head,*p1,*p2;
     int n,i;
     head=NULL;
     for(i=1;i<=a;i++)
       {  
          p1=(struct node*)malloc(sizeof(struct node));
          p1->num=i;
          if(head==NULL) head=p2=p1;
          else{
              p2->next=p1;
              p1->previous=p2;
              p2=p1;
          }
       }
       if(head!=NULL)
         p2->next=head;
       head->previous=p2;
       return head;
  }
  
   void mod(struct node *head,int n)
    {  struct node *p=head,*t;
       int count=1;
       while(p->next!=p)
         {    p=p->next;
              count+=1;
              if(count==3)
                {  count=1;
                   (p->previous)->next=p->next;
                   (p->next)->previous=p->previous;
                   t=p;
                   p=p->next;
                   t->next=NULL;
                }
         } 
       printf("%d",p->num);
    } 
  
   void free_list(struct node *head)
      { struct node *p;
        while(head!=NULL)
          { p=head;
            head=head->next;
            free(p);
          }
      }
   
   int main(void)
     {  int n;
        scanf("%d",&n);
        struct node *p;
        p=create(n);
        mod(p,n);
        free_list(p);
     }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值