约瑟夫环的创造

#include<stdio.h>
#include<stdlib.h>
typedef struct Linklist
{
    int data;
    struct Linklist *next;
}List;
List *CreateHead()
{
     List *headNode=(List *)malloc(sizeof(List));
    headNode->data=-1;
    headNode->next=NULL;
    return headNode;
}
//List *NewNode(int data)
//{
//    List *NewNode=(List *)malloc(sizeof(List));
//    NewNode->data=data;
//    NewNode->next=NULL;
//    return NewNode;
//}
void Tail_insert(List *headNode,int n)
{
    int i;
    List *tail=headNode;
    for(i=1;i<=n;i++)
    {	
    	// 建立循环的关键 
        List *NewNode=(List *)malloc(sizeof(List));
        NewNode->data=i;
        tail->next=NewNode;
        NewNode->next=headNode->next;
        tail=NewNode;
    }
}
void Joseph(List *headNode,int n,int m)//n:表示从第几个开始数,m:表示数到几出去
{
    List *Tail=headNode;
    List *p=headNode->next;//先找从第几个开始数
    while(p->data !=n)
    {
        p=p->next;
    }
    while(p->next !=p)
    {
        int i;
        for(i=1; i<m; i++)
        {
            Tail=p;
            p=p->next;
        }
        printf("出列的人是%d:\n",p->data);
        Tail->next=p->next;//删除节点
        free(p);
        p=Tail->next;
    }
    printf("最后一个出列的人是%d:",p->data);
    free(p);
}
void PrintfList(List *headNode)
{
    List *pmove=headNode;
    while(pmove->next !=NULL)
    {
        pmove=pmove->next;
        printf("%d\n",pmove->data);
    }
}

int main ()
{
    int n,m,k;
    List *List=CreateHead();
    printf("请问你要录入多少个数:");
    scanf("%d",&n);
    printf("请问你要从第几个人开始数(0<m<=%d):",n);
    scanf("%d",&m);
    printf("请问要数到几出列:");
    scanf("%d",&k);
    Tail_insert(List,n);
    Joseph(List,n,m);
    return 0;
}

约瑟夫环难点

1.不知道如何建立一个循环链表

先建立头节点与新节点之间的联系让头指针指向第一个节点,让第一个节点的指针指向头指针指向的节点(第一个节点),让尾巴往后移一个位置,移到创造的节点位置,然后重新创造新的节点,让重新创造的节点的指针指向第一个节点,构成循环。 

2.不知道如何清除,外加判断

1.首先得判断从编号几开始数,即正式开始数数 ,找到这个人的位置

 2.数到几开始出去,利用循环判断,判断到几循环结束

 为什么i要从1开始呢?因为本身到了的那个人就是第一个,相当于已经做了一次循环,列如我假设数到2出局,我本身已经数了1,再数一次就出局了,相当于再做一次循环。

tail所处的位置是删去节点的上一个位置,游戏结束是当最后一个人指向自己时游戏结束。

3.如何删去节点并重新开始循环

tail->next=p->next;

free(p);释放节点空间

p=tail-next         (删除节点)

重新开始循环的条件

 当判断结束,即使游戏已经结束判断出了获胜者。

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值