【约瑟夫环问题(C语言)】

【问题描述】

简化的约瑟夫环 (Joseph) 问题。编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个正整数的密码。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此循环,直至圈内的所有人全部出列为止。

【基本要求】

利用循环链表模拟此过程,按照出列的顺序打印各人的编号

【测试数据】

m=20,n=7;圈内人所持密码: 3,1,7,2,4,8,4。

【测试结果】

正确的结果应为6,1,4,7,2,3,5

问题分析:

首先定义一个结构体,其中包含三个成员变量:编码num,密码code,指针*next

要输入参数:人数n 初始密码m 循环密码,其中循环密码可以存在一维数组中

基本思路:

编写YSF函数(约瑟夫)

    首先创建结点数为n的循环链表,同时填充数据域(num和code)

    然后开始循环,一个个出局

代码:

#include<stdio.h>
#include<stdlib.h>

typedef struct YSFnode{
    int num;
    int code;
    struct YSFnode* next;
}Node,*list;

YSF(int n, int m){//传入人数n,初始密码m
    //输入密码,用数组存储密码
    int a[n];
    int i;
    for(i = 0; i< n;i++){
        printf("输入密码:");
        scanf("%d",&a[i]);
    }
    //创建链表
    list head = NULL, p = NULL, tmp = NULL;
    head = (list)malloc(sizeof(Node));
    p = head;
    p->num = 1;
    p->code = a[0];
    for(i = 1;i < n;i++){
        //创建链表
        tmp = (list)malloc(sizeof(Node));
        tmp->num = i+1;//输入编码
        tmp->code = a[i];//输入密码
        p->next = tmp;//链接
        p = p->next;//后移
    }
    p->next = head;//循环链表
    p = head;//pc重新指向头指针

    //出局循环
    while(p->next != p){//循环结束条件是只剩下一个结点,所以后面还要输出最后这个结点的编码
        for(i = 1; i<m ;i++){
            //用p指针指向要出局的人
            tmp = p;
            p = p->next;
        }
            printf("%d ",p->num);//打印编码
            m = p->code;//更新密码
            tmp->next = p->next;//删除结点
            p = p->next;//后移
    }
    printf("%d",p->num);//打印最后一个编码
}

int main(){
    int n,m;
    printf("输入人数和初始密码(空格隔开):");
    scanf("%d %d",&n,&m);
    YSF(n,m);
    return 0;
}

运行:

在这里插入图片描述

​​​​

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值