约瑟夫(Josephus)环问题

本实验的目的是进一步理解线性表的逻辑结构和存储结构,进一步提高使用理论知识指导解决实际问题的能力。

问题描述: N 个人围成一圈,每个人都有一个编号,编号由入圈的顺序决定,第一个入圈的人编号为 1,最后一个为 N,从第 k (1<=k<=N)个人开始报数,数到 m (1<=m<=N)的人将出圈,然后下一个人继续从 1 开始报数,直至所有人全部出圈,求依次出圈的编号。

 分析:

数据结构设计

约瑟夫问题描述的是循环报数出圈的问题,报数始终围绕同一个方向进行,所以可以使用单向环形链表来存储。

每当有一个人入圈,就创建出一个新的节点,节点间首尾相连,链表不带头结点。

代码

#define _CRT_SECURE_NO_WARNINGS

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

typedef struct node
{
    int local;
    struct node* next;
}LNode, * LinkList;

void CreateLinkList_L(LinkList L, int n)
{
    int i;
    LinkList s, r;
    r = L;

    for (i = 2; i <= n; i++)
    {
        s = (LinkList)malloc(sizeof(LNode));
        s->local = i;
        r->next = s;
        r = r->next;
    }
    r->next = L;
}

void Josephus(LinkList L, int n, int m, int k) //m = 3 , k = 2
{
    int i = 1, j = 1;

    LinkList p, q, s;
    q = new LNode;
    p = L;
    //确定第一个喊话的同学
    while (i < k)
    {
        q = p;
        p = p->next;
        i++;
    }
    while (p->next != p)
    {

        //一个循环用来喊话,一直喊m次
        while (j < m)
        {
            q = p;
            p = p->next;
            j++;
        }
        s = p;
        p = p->next;
        q->next = p;
        printf("%d号淘汰!\n", s->local);
        free(s);
        j = 1;
    }

    printf("%d胜出!", p->local);
}

void main()
{
    LinkList L = (LinkList)malloc(sizeof(LNode));
    L->local = 1;
    int n,a,b;
    printf("请输入人数:");
    scanf("%d", &n);
    printf("第几个人开始:");
    scanf("%d", &b);
    printf("数到第几个:");
        scanf("%d", &a);
    CreateLinkList_L(L, n);
    Josephus(L, n, a, b);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值