(算法)C语言模拟约瑟夫环问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37969433/article/details/82817238

约瑟夫环问题描述

m个人围坐一圈,每人持有一个数字,从第一个人开始从1报数,报到n(第一轮n任意给定)的人出圈,将n改为这个出圈的人所持有的数字,下个人开始从1报数,继续报到n的人出列;依次类推直到所有人出圈。

C语言模拟该过程算法

这里采用带有尾结点的循环单向链表存储玩家信息,p和pre两个指针分别指向报数结点和该结点的直接前驱,并同步移动n-1次,删除p指向的结点直至链表为空即可。

具体代码

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
    int id;//玩家编号
    int pw;//玩家持有的数字
    struct node *next;
}node,*LinkList;
/*
用带头结点的尾插法创建有n个结点的循环链表,并返回尾结点
*/
LinkList CreateList(LinkList head,int n){
    head->next = NULL;//头结点
    head->id = 0;
    node *r = head;//工作指针,跟随最后一个结点
    for(int i=0;i<n;i++){
        node *S = (node*)malloc(sizeof(node));
        S->id = i+1;
        printf("input player%d's password:\n",i+1);
        scanf("%d",&S->pw);
        r->next = S;
        r = S;
    }
    r->next = head->next;//最后一个结点指向头结点;
    return r;
}

void play(LinkList tail,int sum,int pw){
    if(sum<1) return;
    else{
        LinkList pre = tail;
        LinkList p = tail->next;
        int n = (pw%sum==0)?sum:pw%sum;//一轮中最少步数
        while(--n){
            pre = p;
            p = p->next;
        }
        pre->next = p->next;
        int newPw = p->pw;
        printf("player%d out!\n",p->id);
        p = p->next;
        play(pre,--sum,newPw);
    }
}

void main(){
    printf("input sum:\n");
    int sum ;
    scanf("%d",&sum);
    LinkList tail = CreateList((LinkList)malloc(sizeof(node)),sum);
    printf("input initPW:\n");
    int pw ;
    scanf("%d",&pw);
    play(tail,sum,pw);
}

猜你喜欢

转载自blog.csdn.net/qq_37969433/article/details/82817238