约瑟夫环(Josephus)问题:古代某法官要判决n个犯人的死刑,他有一条荒唐的法律,将犯人站成一个圆圈,从第s个人开始数起,每数到第d个犯人,就拉出来处决,然后再数d个,数到的人再处决……直到剩下的最后一个可赦免.
结点类:OneLinkNode:
package com;
/**
* 结点类
* @author zdw
*
*/
public class OneLinkNode
{
public int data;
public OneLinkNode next;
public OneLinkNode(int k)
{
data = k;
next = null;
}
public OneLinkNode()
{
this(0);
}
}
链表类OneLink:
package com;
public class OneLink
{
//头结点
protected OneLinkNode head;
//构造一个空的单向链表
public OneLink()
{
head = null;
}
//只有一个结点的单向链表
public OneLink(OneLinkNode h1)
{
head = h1;
}
//判断链表是否为空
public boolean isEmpty()
{
return head == null;
}
//用随机数构造n个数的链表
public OneLink(int n)
{
OneLinkNode rear,q;
if(n > 0)
{
int k = (int) (Math.random()*100);
head = new OneLinkNode(k);
rear = head;
for(int i = 1; i < n ;i++)
{
k = (int) (Math.random()*100);
q = new OneLinkNode(k);
rear.next = q;
rear = q;
}
}
}
}
Josephus类:
package com;
public class Josephus2 extends OneLink
{
Josephus2() // 构造空的单向循环链表
{
super();
}
Josephus2(int n) // 建立n个结点的单向循环链表
{ // 链表结点值为1到n
this();
int i = 1;
//q新结点,rear尾结点
OneLinkNode q, rear;
if (n > 0)
{
//先创建只有一个结点的单向循环链表
head = new OneLinkNode(i);
//指向自己
head.next = head;
rear = head;
while (i < n)
{
i++;
//新结点
q = new OneLinkNode(i);
//新结点的next字段指向head
q.next = head;
//这里的near是尾结点(第一次就是head)的next字段指向新结点
rear.next = q;
//保存新节点的地址,以便下次循环使用
rear = q;
}
}
}
//计数起点s,d要跳过的个数
public void display(int s, int d) // 解约瑟夫环
{
int j = 0;
OneLinkNode p = head;
while (j < s - 1) // 指针步进到计数起始点
{
j++;
p = p.next;
}
while (p.next != p) // 多于一个结点时循环
{
j = 0;
while (j < d ) // 计数
{
j++;
p = p.next;
}
delete(p); // 删除p的后继结点
p = p.next;
this.output();
}
}
public void delete(OneLinkNode p) // 删除p的后继结点
{
OneLinkNode q = p.next; // q是p的后继结点
System.out.print("delete: " + q.data + " ");
if (q == head) // 欲删除head指向结点时,
head = q.next; // 要将head向后移动
p.next = q.next; // 删除q
}
public void output() // 输出单向链表的各个结点值
{
OneLinkNode p = head;
System.out.print(this.getClass().getName() + ": ");
do
{
System.out.print(p.data + " -> ");
p = p.next;
} while (p != head);
System.out.println();
}
//测试
public static void main(String args[])
{
int n = 5, s = 2, d = 1;
Josephus2 h1 = new Josephus2(n);
h1.output();
h1.display(s, d);
}
}
测试输出结果没有任何问题:
com.Josephus2: 1 -> 2 -> 3 -> 4 -> 5 ->
delete: 4 com.Josephus2: 1 -> 2 -> 3 -> 5 ->
delete: 2 com.Josephus2: 1 -> 3 -> 5 ->
delete: 1 com.Josephus2: 3 -> 5 ->
delete: 3 com.Josephus2: 5 ->
来源:http://www.blogjava.net/supercrsky/articles/171805.html
其实这个题没多难,但是要是在面试的时候问你,现想就来不及了……
分享到:
相关推荐
约瑟夫环问题,也称为约瑟夫环序列或约瑟夫问题,是一个著名的理论问题,源自古罗马的传说。该问题通常用于考察计算机科学中的数据结构和算法,特别是循环链表和数组的运用。在问题中,人们围成一个圈,按照一定的...
该程序以C语言实现的约瑟夫环问题,通过单循环链表结构有效地模拟了这一过程。用户可以输入人数n和初始报数上限m,以及每个人对应的密码,程序将按约瑟夫环规则输出出列顺序。程序设计清晰,逻辑严谨,是理解链表...
根据提供的文件信息,我们可以归纳出该报告主要围绕“约瑟夫环”问题展开,并...通过以上分析可以看出,这份报告详细介绍了使用链表解决约瑟夫环问题的方法和技术细节,为理解和实现这一经典问题提供了一个清晰的思路。
问题描述:约瑟夫环问题的一种描述是:编号为1,2,...,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时...
在本文中,我们将深入探讨约瑟夫环问题的背景、原理以及如何使用链表来求解这一问题,同时分析给定代码的具体实现细节。 ### 约瑟夫环问题概述 约瑟夫环问题起源于古罗马时期的犹太历史学家约瑟夫斯的一个故事。在...
- **单向循环链表**:约瑟夫问题的解决通常采用单向循环链表来存储参与者的编号和密码,这种数据结构能够高效地模拟环形结构,便于实现出局逻辑和新成员加入。 **2. 报数机制** - 报数机制是指从某一位参与者开始...
通过本实验的学习,我们不仅掌握了单向循环链表的基本概念及操作方法,还能够运用这些知识解决实际问题——约瑟夫环问题。在实际编程过程中,我们也深刻体会到了算法设计的重要性以及选择合适数据结构对于提高程序...
本问题涉及到数据结构中的单向循环链表,并通过此数据结构来解决特定的约瑟夫环问题。 #### 二、问题背景与定义 在一个圆形的圈子里有七个人,每个人都被赋予了一个唯一的编号以及一个初始密码。游戏规则是从第一...
约瑟夫问题,又称为约瑟夫环问题,是一个经典的理论问题,源于古犹太历史的一个故事。在数据结构的学习中,它常被用来考察循环链表的操作和算法设计。约瑟夫问题的核心在于模拟一个报数过程,当报到特定数值时,该人...
[问题描述] 编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。...[基本要求] 分别选择顺序表和单向循环链表作为存储结构模拟整个过程,并依次输出出列的各人的编号。
在本次实验中,主要目标是设计并实现一个C语言程序来解决约瑟夫环问题。约瑟夫环是一个经典的计算机科学问题,涉及到一系列人围成一圈进行报数游戏。在这个游戏中,每个人都被赋予一个初始密码(一个正整数),并...
相比传统的单向链表或数组,双向循环链表提供了更加灵活的操作方式,能够更高效地处理节点的插入和删除,尤其适合解决类似约瑟夫问题这类需要频繁改变数据结构的问题。 具体而言,改进版约瑟夫问题通过双向循环链表...
### 约瑟夫环问题解析 #### 一、问题背景与定义 约瑟夫问题是一种经典的计算机科学问题,属于数据结构与算法领域中的一个重要案例。这个问题源自古罗马历史学家约瑟夫斯的一个故事,讲述了一群人围成一个圈,并...
此程序通过构建一个单向链表来模拟约瑟夫问题中的环形结构,并实现相应的算法逻辑。 #### 约瑟夫问题背景 约瑟夫问题源自古罗马时期,描述了一群人围成一圈按特定规则报数,每报到某个固定数字的人将被淘汰,直至...
这个实验旨在让学生掌握链表的基本操作,如插入、删除和遍历,同时理解约瑟夫环问题的解决策略,锻炼逻辑思维能力和问题求解技巧。通过编写这样的程序,可以加深对数据结构和算法的理解,对于计算机科学的学习至关...
- **基本要求**:程序需接收用户输入的n(人数)、m(报数上限)和每个人的密码,构建一个单向循环链表,模拟约瑟夫环过程,并输出出列顺序。同时,程序应能处理非法输入。 - **算法思想**:首先构建循环链表,用...
约瑟夫环问题是一个典型的应用实例,它利用单向循环链表来模拟过程。学生需要设计一个程序,根据给定的报数上限值m和人员密码,按照出列顺序打印出人员编号。这个问题强调了链表的插入、删除和遍历操作。 栈是一种...