约瑟夫环问题链表实现(Java)

约瑟夫环问题链表实现(Java)面试中可能经常会遇到约瑟夫环问题,逻辑上很简单,就是看怎么实现了,一般而言,最简单最直观的就是利用链表,然后构建一个循环结构,正好是环,最后计算出结果。遍历环形链表会是一个无限循环,如果链表中的数据逐渐减少,不控制终究会一个不剩,这又不满足我们问题的求解,因此我们需要定义出循环结束的条件,按照约瑟夫环的规则,只剩下一个的时候就结束,在环形链表结构中,那就是结点本身的下一个节点就…

大家好,又见面了,我是你们的朋友全栈君。

    面试中可能经常会遇到约瑟夫环问题,逻辑上很简单,就是看怎么实现了,一般而言,最简单最直观的就是利用链表,然后构建一个循环结构,正好是环,最后计算出结果。

    遍历环形链表会是一个无限循环,如果链表中的数据逐渐减少,不控制终究会一个不剩,这又不满足我们问题的求解,因此我们需要定义出循环结束的条件,按照约瑟夫环的规则,只剩下一个的时候就结束,在环形链表结构中,那就是结点本身的下一个节点就是它自己。这样就可以结束遍历了。最后打印出剩下的结点,问题解决。

这里给出Java版本的实现:

package com.xxx.algorithm.wh;
//约瑟夫环java实现
//约瑟夫环问题的起源来自犹太历史学家约瑟夫和他的朋友以及39其余的犹太人,总共41人为了躲避敌人,藏在一个山洞中,
//39个犹太人决定宁愿死也不被敌人抓到,于是决定自杀,所有人排成一个圈,由第一个人开始报数,每当数到3,就自杀。
//这个游戏接着从自杀的位置开始,还是从1数到3。依次类推,约瑟夫将朋友和自己安排在了16和31的位置,最后顺利逃过了
//自杀这一劫,因为最后就剩他一个人了。
public class JosefCircleMain {
	
	public static void count(int n){
		//数到3出局,中间间隔两个人
		int k = 3;
		//头结点不存储数据
		Node head = new Node();
		Node cur = head;
		//循环构造这个链表
		for(int i=1;i<=n;i++){
			Node node = new Node(i);
			cur.next = node;
			cur = node;
		}
		//链表有数据的部分首尾相连形成一个环。
		cur.next = head.next;
		//统计开始的时候,刨去头结点,然后从第一个有数据的结点开始报数
		Node p = head.next;
		//循环退出的条件是最后只剩一个结点,也就是这个结点的下一个结点是它本身
		while(p.next!=p){
			//正常报数的遍历逻辑
			for(int i=1;i<k-1;i++){
				p = p.next;
			}
			//当数到3的时候,出局
			System.out.print(p.next.data+"->");
			p.next = p.next.next;
			p = p.next;
		}
		//最后剩下的一个结点
		System.out.println("(left:"+p.data+")");
	}

	public static void main(String[] args) {
		//以4个人为例,1234 : 最先出局的是3,然后剩下412,接着2出局,剩下41,这时候就是4出局,最后剩下1.
		count(4);
		//41个人为例,就是约瑟夫环的本身了,最后剩下的是31
		count(41);
	}

}

class Node{
	int data;
	Node next;
	public Node(){}
	public Node(int data){this.data = data;}
}

    一般的链表,如果没有特别的说明,头结点是有数据的,但是这里情况比较特殊,我们构建了一个头结点没有数据的空节点,然后将链表的首尾相连,这个首其实也不是头结点,而是头结点的下一个结点,用图表示就是如下:

约瑟夫环问题链表实现(Java)

    首次遍历的时候,我们是从1开始的,所以代码中有这样的一句:

约瑟夫环问题链表实现(Java)

运行程序,打印结果:

3->2->4->(left:1)
3->6->9->12->15->18->21->24->27->30->33->36->39->1->5->10->14->19->23->28->32->37->41->7->13->20->26->34->40->8->17->29->38->11->25->2->22->4->35->16->(left:31)

打印结果既验证了只有4个结点的情况,也验证了约瑟夫环的本身的结论。 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/136160.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 数据可视化之美 — 以Matlab、Python为工具

    数据可视化之美 — 以Matlab、Python为工具在我们科研、工作中,将数据完美展现出来尤为重要。数据可视化是以数据为视角,探索世界。我们真正想要的是—数据视觉,以数据为工具,以可视化为手段,目的是描述真实,探索世界。下面介绍一些数据可视化的作品(包含部分代码),主要是地学领域,可迁移至其他学科。Example1:importnumpyasnpimportmatplotlib.pyplotasplt#创建随机数n=100000x=np.random.randn(n)y=(1.5*x)+np.ra

    2025年6月15日
    0
  • 51单片机SG90舵机控制原理

    51单片机SG90舵机控制原理舵机三根线的接法:黄线接信号线,红线接vcc,褐色线接GND舵机控制原理:通过控制PWM来控制舵机转动的角度,关于PWM的知识可以去智能小车专栏进行学习,转动周期设置为20ms,控制高电平的时间来进行舵机转动的角度。对于180°舵机t=0.5ms——————-舵机会转动0°t=1.0ms——————-舵机会转动45°t=1.5ms——————-舵机会转动90°t=2.0ms——————-舵机会转动135°t=2.5ms——————-舵机会…

    2022年6月16日
    39
  • 命令行连接mongodb_yum安装mongodb

    命令行连接mongodb_yum安装mongodb情况:1.使用xmanage能远程链接centos

    2022年8月21日
    4
  • jprofiler监控jvm_怎么检测jps

    jprofiler监控jvm_怎么检测jps很多人在学习java的时候只是对java粗略的学了一遍,很少有人能了解jvm层面的一些东西,比如我们想看目前有多少个java进程,可以在命令行执行jps。下面我们来说说jps的一些详细的用法。jps输出正字运行的相关进程信息jps-v输出传递给jvm参数jps-l输出模块名以及包名,如果是jar则出输jar文件全名jps-m输出传递给jvm参数jps-mlv输出进程号,包名,虚拟…

    2022年9月2日
    3
  • 玩玩webgame开发(4):游戏数据结构设计[通俗易懂]

    玩玩webgame开发(4):游戏数据结构设计[通俗易懂]很久没做更新了。最近比较忙碌,手头的webgame也都放下。最近很想念我的小webgame了,回来继续写。上篇玩玩webgame开发(3):自动战斗实现以及一些游戏细节(下)http://playfish.iteye.com/blog/267275在高峰期时候发表的,结果被火速沉底了。。。汗好了,不小心有说了好多废话,言归正传。=============数据结构设计是门…

    2022年6月2日
    37
  • 安卓端口占用_查看端口号命令

    安卓端口占用_查看端口号命令android查看端口号被占用

    2022年7月27日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号