约瑟夫环经典版--For初学者

这是一个经典的问题,内容是click here。本文章要实现的是:一共n个人,从第k个人开始报数,数到m的淘汰。从他的下一个人接着数,直到剩余一个人为止。
首先,生成n个人的单链表,并从第k个人开始生成。在这里插入图片描述
首尾相接后,如图:
在这里插入图片描述
第一个节点数据元素存的是k,也就是说从第1个开始数到m,
在这里插入图片描述
此时q指向m-1,p指向第m个元素。将第p个元素删除即可,然后循环遍历,知道最后一个人剩下。
思路就是这样。
编译环境为Code::Blocks,由于能力有限,难免有bug,仅给读者提供思路。
代码如下:

#include<stdio.h>
#include<string.h>

typedef int ElemType;

typedef struct node
{
    ElemType data;
    struct node *next;
}LNode;

void Josephus(int n,int m,int k)
{
    LNode *q,*p;
    int i;
    p=(LNode *)malloc(sizeof(LNode));//申请一个新节点
    q=p;
    for(i=1;i<n;i++)        //for循环吧n-1个人排上号
    {
        q->data=k;          //第一个节点为k,即从k开始
        k=k%n+1;            //避免k=n的情况
        q->next=(LNode *)malloc(sizeof(LNode));
        q=q->next;          //q一直指向最新的节点
    }
    q->data=k;              //q指向第n个人,k也是第n个数
    q->next=p;              //尾指针指向头结点,形成循环单链表
    printf("依次淘汰的人\n");
    while(p->next!=p)       //判断是否剩余一个人
    {
        for(i=1;i<m;i++)
        {
            q=p;            //当从循环出来q在m-1处
            p=p->next;      //当从循环出来的时候,p节点在m位置处
        }

        q->next=p->next;//q指向m+1的节点,即淘汰第m个人

        printf("%4d",p->data);
        free(p);
        p=q->next;
    }
    printf("\n剩的最后一人\n");
    printf("%4d",p->data);
}
int main()
{
    int n,m,k;
    printf("输入人数n,总报数m,开始号k\n");
    scanf("%d%d%d",&n,&m,&k);
    Josephus(n,m,k);
    return 0;
}

运行后结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/a_52hz/article/details/82917747