约瑟夫生死游戏

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

typedef int ElemType;

typedef struct LNode{

    ElemType data;//数据域

    struct LNode *next;//指针域

} LinkList;

//初始化单链表

int InitList(LinkList *L){

    // L=(LinkList *)malloc(sizeof(LinkList));

    if (L==NULL) return 0;//分配失败

    L->next=NULL;//空表,类似于顺序表n=0

    printf("initList successfully\n");

}

//头插法创建链表

int HeadCreateList(LinkList *L,ElemType k){

    if(k<1) return 0;

    LinkList *temp;

    if (temp==NULL) return 0;//分配失败

    int i=1;

    while(i<=k){

        temp=(LinkList *)malloc(sizeof(LinkList));

        temp->data=i;//交替指向添加元素

        temp->next=L->next;//链表循环赋值

        L->next=temp;

        i++;

    }

    printf("Created successfully\n");

}

//尾插法创建链表

int FootCreateList(LinkList *L,ElemType k){

    //非法操作或创建失败

    if(k<0) return 0;

    LinkList *temp,*LCopy;

    LCopy=L;

    int i=1;

    while(i<=k){

        temp=(LinkList *)malloc(sizeof(LinkList));

        if(temp==NULL) return 0;

        temp->data=i;

        L->next=temp;

        L=L->next;//链表位置始终保持在最后

        i++;

    }

    L->next=LCopy->next;//尾结点连接头结点后第一个元素结点

    printf("Created successfully\n");

}

//打印操作

void PrintList(LinkList *L,ElemType k){

    LinkList *temp=L;

    temp=temp->next;//从头结点指向首结点

    for (int i = 0; i < k; ++i)

    {

        printf("%d\n",temp->data);

        temp=temp->next;

    }

    printf("print successfully\n");

}

//递归调用,每隔m个删除一个,直至所剩k人

ElemType DeleteElemList(LinkList *L,int m,int k,int *n){

    int i=1;

    //从j位往后数m-1位,将要删除元素的前一位

    for (; i <= m-1; ++i)

    {  

        L=L->next;

    }

    // printf("所删元素为:%d \n",L->next->data);//输出目标元素

    L->next=L->next->next;//跳过目标元素

    (*n)=(*n)-1;//长度减1

    //未达到k人时不断递归调用

    if (k<(*n)) DeleteElemList( L, m, k , n);

   

}

int main()

{

    //n人,从j开始计数,第m个人使其出列,直至所剩k人

    int n,m,j,k;

    LinkList *L;//声明一个指向单链表的带头指针L

    L=(LinkList *)malloc(sizeof(LinkList));

    InitList(L);

    //插入n元素,即n人

    printf("输入n人\n");

    scanf("%d",&n);

    if (n<1){

        printf("非法输入");

        return 0;

    }

    //为链表创建n结点

    FootCreateList(L,n);

    //打印

    // PrintList(L,n);

    printf("从j开始计数\n");

    scanf("%d",&j);

    if (j>n){

        printf("非法输入");

        return 0;

    }

    printf("第m个人使其出列\n");

    scanf("%d",&m);

    if (m>=n){

        printf("非法输入");

        return 0;

    }

    printf("直至所剩k人\n");

    scanf("%d",&k);

    if (k>=n){

        printf("非法输入");

        return 0;

    }

    //调整正确位置到j位

    for (int i = 0; i < j; ++i)

    {  

        L=L->next;//此时temp指到目标位置

    }

    //开始操作

    DeleteElemList(L,m-1,k,&n);

    // printf("最后的n为%d\n",n);

    printf("所剩元素为\n");

    PrintList(L,n);

    return 0;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值