c之约瑟夫环问题

【约瑟夫环】

N个人围成一圈,从第k个数开始报数,第M个被杀掉,重复这一步骤,直到所有的人都被杀掉。

【运用的方法】

本代码使用的是不带头结点的循环链表,相比于带头结点的链表,不带头结点的链表无非就是给头指针的数据域赋值而已。

找到开始计数的地方,到 M 个之后,删除第 M 个节点。然后继续计数并删除

【错误点】

在第一次试着编写这段代码的时候,找到第一个需要删除的节点,直接 free 掉,这样的话原本的循环链表就会断掉,所以在 free 之前,需要记住 前后两个节点,然后才能 free,再将链表重新连接起来,形成新的循环链表。

【代码实例】

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct Node{
           int data;
           struct Node *next;
}Lnode,*LinkList;
int main()
{
         int n,k,m;
         scanf("%d %d %d",&n,&k,&m);
         if(n<0)
                  return 0;
         else
        {
                  LinkList H;
                  H=(Lnode *)malloc(sizeof(Lnode));   //第一个结点
                  if(H==NULL)
                              printf("no memory available!\n");
                   else
                   {
                               H->data=1;  //第一个结点的值是1;
                               H->next=NULL;
                               Lnode *p;   //p用来指向第一个结点,r用来添加节点
                               p=H;//p指向第一个结点
                               for(int i=2;i<=n;i++)
                               {
                                        Lnode *r;
                                        r=(Lnode *)malloc(sizeof(Lnode));   //申请空间,指向添加的结点
                                         r->data=i;
                                         r->next=NULL;
                                         p->next=r;
                                         p=r;
                               }
                     p->next=H;
                     }
           Lnode *s;
           Lnode *r;
           s=H;
           while(s->data!=k)
          {
                     s=s->next;
           }
            int number=6;
            while(number-1)

            {
                        int num=1;
                        while(num!=m-1)

                        {
                                   s=s->next;
                                   num++;
                         }
                           r=s->next->next;
                           printf("%d ",s->next->data);
                           free(s->next);
                           s->next=r;
                           s=r;
                            number--;
        }
        printf("%d ",s->data);

      }
       return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值