约瑟夫环问题(C语言循环链表)

1、约瑟夫环问题(C语言循环链表)

我相信大家都可以画出这个图,知道大体的解题的思想,但是却不知道代码该怎么下手,因此,下面我直接上代码,代码中该注释的地方我都进行了注释,希望到大家有帮助;




#include<stdio.h>
#include <mm_malloc.h>


typedef struct Node {

    int num;
    int password;
    struct Node *next;

} Node, *LinkList;


int main() {
    void JOsephus();
    JOsephus();
}

void JOsephus() {
    //定义需要用到的变量
    int n = 0, m = 0, j = 0, pwd = 0;// n代表多少人参与, m是初始的期望值, j用于方便操作,pwd代表密码
    Node *p, *r, *pre, *q;// p指向新开辟的节点  r始终指向链表中的最后一个节点 q存放要被释放的节点 pre指向p的前驱节点

    // 申请初始化循环单链表
    LinkList L = (Node *) malloc(sizeof(Node));
    if (L == NULL) {
        printf("申请内存空间失败!\n");
        return;
    }
    r = L;
    L->next = NULL;

    printf("请输入参与的人数n:");
    scanf("%d", &n);

    for (int j = 1; j <= n; j++) {
        p = (Node *) malloc(sizeof(Node));
        if (p != NULL) {
            printf("请输入第%d个人的密码:", j);
            scanf("%d", &pwd);
            p->num = j;
            p->password = pwd;
            //   p->next = r->next;
            r->next = p;
            r = p;
        }

    }
    r->next = L->next; // 这一步这样写是因为实际情况空节点并不是一个人,所有循环的时候没必要包括,挺妙的
    //上面就是循环表的初始化,下面开始进行操作

    printf("请输入第一个报数的上限值m(m>0):");
    scanf("%d", &m);
    printf("============================\n");
    printf("出列顺序:");

    pre = L;
    p = L->next;
    //循环结束的条件就是还剩下一个人
    while (n != 1) {

        // 大部分人都可以想到我们需要一个指向一直发生变化的指针,并且有相应的指针指向,他的前驱节点
        j = 1;
        while (j < m) {
            pre = p;
            p = p->next;
            j++;
        }
        printf("%d->", p->num);
        m = p->password;
        n--;

        // 下面几步是为了删除出列的节点,并且释放
        pre->next = p->next;
        q = p;
        p = p->next;
        free(q);

    }
    printf("%d\n", p->num);//最后还剩一个人的序号需要输出
}

  • 5
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值