练习一道经典链表题目

题目分享:约瑟夫问题

让我们举个例子来看看

我们可以看到假设是报号为三的人走,那我们只要定义一个count 当他增长到三的时候,让此时循环到的人走,那我们是不是的需要一个指针进行循环呢,那我们还需要一个指针进行记录辅助这个遍历指针,否则,将这个指针指向的空间进行释放,那么就找不到链表了,所以我们移动一个位置,count就加一次,然后一前一后两个指针进行挪动。

1.我们首先得实现一个头尾相连的循环链表

我们之前学习单链表,所以这些代码对我们很好实现

typedef struct ListNode listnode;
listnode* chuang(int x)
{
  listnode* newnode=(listnode*)malloc(sizeof(listnode));
  if(newnode==NULL)
  {
    exit(1);
  }
  newnode->val=x;
  newnode->next=NULL;
  return newnode;
}

首先我们写一个为单独数据开辟空间的函数

listnode* list(int x)
{
   listnode* head=chuang(1);
   listnode* ps=head;
   for(int i=2;i<=x;i++)
   {
     ps->next=chuang(i);
     ps=ps->next;
   }
   ps->next=head;
   return head;
}

我们再函数中实现对n个人的空间开辟,然后将这几个空间使用单链表的形式进行链接,最后返回头结点的指针。

接着我们是实现遍历次数符合则释放空间,剩下最后一个数据时候,在循环单链表中的特点是什么,那就它的尾结点的next指针指向的是自己的头结点。所以这个就是我们的循环遍历的终止条件。

int ysf(int n, int m ) {
   
   listnode* head=list(n);
   listnode* ps=head;
   listnode* prev=NULL;
   int count=1;
   while(ps->next!=ps)
   {
        
        if(count==m)
        {
           prev->next=ps->next;

            free(ps);
            ps=prev->next;
            count=1;//每次走掉一个人我们就需要把count重新定义成1,在进行次数的累计
        }
        else 
        {
            prev=ps;
            ps=ps->next;
            count++;
        }
        
   }
   return prev->val;

}

ok了

  • 11
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值