用单向循环链表实现约瑟夫环问题

约瑟夫环的问题和种类有很多,这是一道基本的约瑟夫环问题,通过单向循环链表实现模拟此过程。

代码如下:

#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
    int num;
    int password;
    struct Node *next;
}CircleNode,*CircleList;

CircleList Create(int n);
void Knockout(CircleList L,int n,int m);

int main(void)
{
    printf("Enter the upper limit m: ");
    int m;
    scanf("%d",&m);
    printf("Enter the number of people: ");
    int n;
    scanf("%d",&n);
    CircleList L=Create(n);
    printf("The order of knockout: ");
    Knockout(L,n,m);
    return 0;
}

CircleList Create(int n)
{
    CircleList L=(CircleList)malloc(sizeof(CircleNode));
    L->next=L;
    CircleNode *rear=L;
    printf("Enter the password for person 1-%d: ",n);
    for(int i=1;i<=n;i++)
    {
        CircleNode *p=(CircleNode*)malloc(sizeof(CircleNode));
        scanf("%d",&p->password);
        p->num=i;
        rear->next=p;
        rear=p;
    }
    rear->next=L;
    return L;
}

void Knockout(CircleList L,int n,int m)
{
    CircleNode *cur=L;
    CircleNode *prev=L;
     while(n--)
    {
        for(int i=1;i<=m;)
        {
            if(cur->next!=L)
            {
                prev=cur;
                cur=cur->next;
            }
            else
            {
                prev=L;
                cur=L->next;
            }
            ++i;
        }
        printf("%d ",cur->num);
        m=cur->password;
        prev->next=cur->next;
        free(cur);
    }
}

/*
测试集
输入: m=20 n=7  密码:3 1 7 2 4 8 4
输出: 6 1 4 7 2 3 5
*/

/*
void Print(CircleList L)
{
    CircleNode *p=L->next;
    while(p!=L)
    {
        printf("%d ",p->num);
        p=p->next;
    }
}
*/

原文地址:https://www.cnblogs.com/CuteyThyme/p/10679352.html

时间: 2024-10-10 23:08:40

用单向循环链表实现约瑟夫环问题的相关文章

单向循环链表(约瑟夫环)

#include<stdio.h> #include<stdlib.h> #define N 10 typedef struct node{ int  data; struct node * next; }ElemSN; ElemSN*Createlink(int a[],int n){ int i; ElemSN*h=NULL,*p,*t; for(i=0;i<N;i++){ p=(ElemSN*)malloc(sizeof(ElemSN)); p->data=a[i

(java描述)关于链表的代码-----单双、循环链表、约瑟夫环、多项式相加

将链表头尾倒置 将几个链表合并成一个新的链表,将链表中重复的节点去掉,并按大小排序 双向循环链表 单向循环链表(约瑟夫循环) 多项式相加 程序源代码 单链表.单向循环链表结点类 package javab; public class Node { int data; Node next; public Node(int data){ this.data=data; } } 第一题代码: package javab; import java.util.Scanner; public class I

C++循环链表解决约瑟夫环问题

约瑟夫环问题可以简单的使用数组的方式实现,但是现在我使用循环链表的方法来实现,因为上午看到一道面试题规定使用循环链表解决约瑟夫环问题. 什么是约瑟夫环? “约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周围的人全部出列.”(百度百科中的解决办法列出了很多,可以看到循环链表并不是最简单的方法) 这道面试题考察了循环链表的“创建”,

循环单向链表(约瑟夫环)

#include <stdio.h> #include <stdlib.h> typedef struct List { int data; struct List *next; }List; //创建循环单向链表n为长度 List *list_create(int n) { List *head, *p; int i; head = (List *)malloc(sizeof(List)); p = head; p->data = 1; //创建第一个结点 for (i =

C++ 用循环链表解决约瑟夫环问题

约瑟夫环问题 已知 n 个人(n>=1)围坐一圆桌周围,从 1 开始顺序编号,从序号为 1 的人开始报数,顺时针数到 m 的那个人出列.下一个人又从 1 开始报数,数到m 的那个人又出列.依此规则重复下去,直到所有人全部出列.请问最后一个出列的人的初始编号. 要求 输入人数 n,所报数 m,输出最后一个人的初始编号. 解决思路 首先因为是圆桌问题,使用链表解决的话需要构建循环链表. 接着是出列问题,这里我的设计思路是将指向链表的指针移动到需要出列的人的位置,然后根据正常的链表删除进行操作即可.

javascript中使用循环链表实现约瑟夫环问题

1.问题 2.代码实现 /** * 使用循环链表实现解决约瑟夫环问题 * */ //链表节点 function Node(element){ this.element = element; this.next = null; } //定义链表类 function LList(){ this.head = new Node("head"); this.head.next = this.head; this.find = find; this.insert = insert; this.f

用循环链表解决约瑟夫环的问题

约瑟夫环问题简介 约瑟夫环问题的原来描述为,设有编号为1,2,--,n的n(n>0)个人围成一个圈,从第1个人开始报数,报到m时停止报数,报m的人出圈,再从他的下一个人起重新报数,报到m时停止报数,报m的出圈,--,如此下去,直到所有人全部出圈为止.当任意给定n和m后,设计算法求n个人出圈的次序.  稍微简化一下. 问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数.求胜利者的编号. 解题思路 将每个人的编号作为结点值,因为报数是循环着来的,故可

用循环链表解决约瑟夫环问题

约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周围的人全部出列. 下面我们用循环列表模拟这个过程: 1 //节点定义与单链表相同,在此省略 2 //use cyclical linked list to solve josephus problem 3 template <typename Type> class Linked

用循环链表实现约瑟夫环问题

什么是约瑟夫环问题? 而这实际上就是一个经典的数学问题: 而用一个更生活化的例子来阐述:几个人围坐在一张圆桌上,然后开始数数,数到指定数则淘汰,然后再重1开始数,直到还剩最后一个人则为胜利者. 而具体代码如何来实现呢? 首先还是基于上次的那个链表进行扩展: