数据结构上机作业1-约瑟夫环

1.问题描述

约瑟夫(Joseph)问题的一种描述是:设编号为1,2,…,n的n(n>0)个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。开始时任选一个整数作为报数上限值m,从一个人开始顺时针自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有的人全部出列为止。要求设计一个程序模拟此过程,求出出列顺序。

2.设计要求

设计一个程序,以人机交互方式执行,用户指定约瑟夫环游戏的总人数n和初始的报数上限m,然后输入每个人所持有的密码key。模拟约瑟夫环,从头开始报数,直到所有的人出列。系统按照出列顺序给出编号。

3.代码实现

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

typedef struct Node
{
    /*密码,编号,指向下一结点的指针*/
    int pwd;
    int num;
    struct Node *next;
}Node,*LinkList;

//创建一个新的链表
LinkList CreateList(int n,Node *L)
{
    LinkList p,s;
    int i;
    s=L;
    //依次创造结点,并输入密码
    for(i=1;i<=n;i++)
    {
        p=(Node*)malloc(sizeof(Node));
        p->num=i;
        printf("输出第%d个人的密码:",i);
        scanf("%d",&p->pwd);
        s->next=p;
        s=p;
    }
    L=L->next;
    s->next=L;
    //返回一个创建好了的单循环链表
    return L;
}

//输出信息 ,m是初始密码,n是总人数
void PrintList(int m,int n,Node* L)
{
    LinkList p;
    //x来保存新的密码
    int x,i;
    p=L;
    printf("\n输出顺序(编号,密码):");
    //找到第一个要出局的人
    for(i=1;i<m;i++)
      p=p->next;
    while(n)
    {
        x=p->next->pwd;//此时密码更新了
        //输出编号和所持有的密码
        printf("%d(%d)  ",p->next->num,x);
        //出局
        p->next=p->next->next;
        for(i=1;i<x;i++)
            p=p->next;
        n--;
    }
}

int main()
{
    Node L;
    int m,n;
    printf("输出总人数:");
    scanf("%d",&n);
    printf("输入起始密码:");
    scanf("%d",&m);
    //调用函数,进行输出
    CreateList(n,&L);
    PrintList(m,n,&L);
}

猜你喜欢

转载自blog.csdn.net/zyf2333/article/details/78564839