Josephus问题:设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m的人出列,然后从出列的下一个人重新开始报数,数到第m的人又出列。如此反复直到所有的人全部出列为止。

  思路:构建一个没有头结点的循环链表,实现自己的删除函数,数到第几个结点就把这个结点从链表中删除,然后重新数。

  难点在于写删除函数。

  代码如下:

 

#include <stdio.h>
#include <stdlib.h> typedef struct student * PNode; typedef struct student{
int data;
PNode next;
}Node; PNode create(int n)
{
PNode head=(PNode)malloc(sizeof(Node));
PNode p;
int data=;
p=head;
printf("请输入结点的值\n");
scanf("%d",&data);
p->data=data;
while(--n)
{
p->next=(PNode)malloc(sizeof(Node));
p=p->next;
printf("请继续输入结点的值\n");
scanf("%d",&data);
p->data=data;
}
p->next=head;
return head;
}
void print(PNode link)
{
PNode head,p;
if(link==NULL) return;
head=link;
p=link;
while(p->next!=head)
{
printf("%d ",p->data);
p=p->next;
}
printf("%d\n",p->data);
} PNode del(PNode link,int num)
{
PNode head=link;
PNode p=link;
PNode temp;
if(link==NULL)
{
// printf("链表为空");
return NULL;
}
// printf("要删除结点的值为%d\n",num);
//删除头结点
if(p->data==num)
{
if(p->next==head) //只剩下一个结点的情况
{
// printf("链表删除完毕。\n");
free(link);
return NULL;
}
while(p->next!=head)
p=p->next;
temp=p->next;
p->next=p->next->next;
head=p->next;
free(temp);
return head;
}
//删除非头结点
while(p->next->data!=num && p->next!=head)
{
p=p->next;
}
if(p->next==head)
{
// printf("没有找到这样的结点。\n");
return head;
}
temp=p->next;
p->next=p->next->next;
free(temp);
return head;
} void Josepus(PNode link,int n,int k,int m)
{
if(link==NULL)
{
printf("链表为空\n");
return;
}
printf("打印出列的顺序:");
PNode p=link;
int r=k+m-; //r为链表要移动的次数,根据图示来进行r大小的确认
while(r--)
{
p=p->next;
}
printf("%d ",p->data);
p=del(p,p->data);
while(p!=NULL)
{
r=m-;
while(r--)
{
p=p->next;
}
printf("%d ",p->data);
p=del(p,p->data);
}
printf("\n");
} int main(void)
{
int n,num;
int s,m;
printf("请输入要创建多少个结点\n");
scanf("%d",&n);
PNode link=create(n);
printf("打印初始链表\n");
print(link);
printf("请输入要从第几个人开始报数\n");
scanf("%d",&s);
printf("请输入要报多少个人\n");
scanf("%d",&m);
Josepus(link,n,s,m);/* 测试删除函数用地
while(1)
{
printf("请输入要删除的结点的值\n");
scanf("%d",&num);
link=del(link,num);
if(link==NULL)
break;
printf("打印删除后的链表\n");
print(link);
}
*/
return ;
}

程序猿必读

用循环链表实现Josephus问题的更多相关文章

  1. 循环链表Josephus问题(c,cpp)

    问题描述: 设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m个的人出列,然后从出列的下一个人重新开始报数,数到第m个的人又出列,.......,如此反复直到所有的人出列为止. Joseph ...

  2. Josephus环类问题,java实现

    写出一个双向的循环链表,弄一个计数器,我定义的是到三的时候,自动删除当前节点,很简单. package Com; import java.util.Scanner; /* * 约瑟夫环问题,有n个人组 ...

  3. 约瑟夫(环)问题(Josephus problem)

    问题描述:皇帝决定找出全国中最幸运的一个人,于是从全国选拔出 n 个很幸运的人,让这 n 个人围着圆桌进餐,可是怎么选择出其中最幸运的一个人呢?皇帝决定:从其中一个人从 1 开始报数,按顺序数到第 k ...

  4. 1009: josephus问题

    1009: josephus问题 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 549  Solved: 227 Description josephus ...

  5. 华为面试题——约瑟夫问题的C++简单实现(循环链表)

    /*     author:jiangxin     Blog:http://blog.csdn.net/jiangxinnju     Function:method of Josephus que ...

  6. josephus问题

    问题描述 n个人围成一圈,号码为1-n,从1开始报数,报到2的退出,剩下的继续从1开始报数,求最后一个人的号码. 算法分析 最直观的算法是用循环链表模拟.从首节点开始,不断删除第二个节点,直到只剩一个 ...

  7. Josephus

    利用循环链表模拟约瑟夫问题,把自杀的人的顺序排列出来 代码如下: #include<stdio.h> #include<stdlib.h> typedef int status ...

  8. 约瑟夫问题(Josephus Problem)的两种快速递归算法

    博文链接:http://haoyuanliu.github.io/2016/04/18/Josephus/ 对,我是来骗访问量的!O(∩_∩)O~~ 约瑟夫问题(Josephus Problem)也称 ...

  9. 习题3.10 约瑟夫环 josephus问题

    /* assume a header */ /* 双向循环链表 */ struct Node; typedef struct Node * PtrToNode; typedef PtrToNode L ...

随机推荐

  1. E20170623-ts

    filter   n. 滤波器; 滤光器; 滤色镜; [化] 过滤器; mass   n. 大量,大多; 块,堆,团; [物理学] 质量; 弥撒曲; assignment  n. 分给,分配; 任务, ...

  2. B. Trees in a Row(cf)

    B. Trees in a Row time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  3. All Discs Considered(拓扑排序)

    http://poj.org/problem?id=1778 题意:有两个DVD,第一个DVD上有编号为1~n1的安装包,第二个DVD上有编号为n1+1~n1+n2的安装包,给出m组关系(a,b) 表 ...

  4. P4280 [AHOI2008]逆序对

    传送门 有一个不会证明的贪心:从左到右考虑每一个位置,然后在每一个位置都贪心选取能让该位置构成的逆序对最少的数.判断逆序对的话只要记一下前缀小于等于某数的总数和后缀小于等于某数的总数就行了 //min ...

  5. [Swift通天遁地]三、手势与图表-(8)制作股市中常用的蜡烛图表

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  6. centos源更新

    .备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup .下载新的CentOS-Base.r ...

  7. 尝试安卓与js交互

    1.android中利用webview调用网页上的js代码. Android 中可以通过webview来实现和js的交互,在程序中调用js代码,只需要将webview控件的支持js的属性设置为true ...

  8. ACM_汉诺塔问题(递推dp)

    Problem Description: 最近小G迷上了汉诺塔,他发现n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列.由于发生错移产生的系列就增加了,这种错误是放错了 ...

  9. C# 自己用到的几个参数转换方法

    /// <summary> /// Method:CommandHelper /// Author:Liuyangyi /// Data:2016-05-10 /// </summa ...

  10. Java学习笔记_网络+多线程

    支持同时收发的客户端和服务器端 客户端 import javax.swing.*; import java.awt.*; import java.io.*; import java.net.*; im ...