单向环形链表介绍以及约瑟夫问题分析
创始人
2024-02-19 23:38:31
0

❤️一名热爱Java的大一学生,希望与各位大佬共同学习进步❤️

🧑个人主页:@周小末天天开心

各位大佬的点赞👍 收藏⭐ 关注✅,是本人学习的最大动力

感谢!

📕该篇文章收录专栏—数据结构

目录

单向环形链表

约瑟夫问题

创建Boy类,用来存放数据

创建一个单向环形链表类

构建一个单向环形链表

思路

图解

程序

遍历环形链表

思路

图解

程序

根据用户输入,删除节点

思路

图解

程序

编写Joseph类进行演示

查看输出结果


单向环形链表

从判断一个单链表是否存在循环而扩展衍生的问题,有则称之为有环链表问题,也就是经典的约瑟夫问题,也称为约瑟夫环。

如下图所示:

约瑟夫问题

约瑟夫(约瑟夫环,Joseph)问题为:

设编号为1,2,3,……,n 的n个人围坐在一圈,约定编号为k(1 <= k <= n)的人从1开始报数,数到m的那个人出列,他的下一位又从1开始报数,数到m的那个人又出列,以此类推,直到所有人出列为止,由此产生一个出队编号的序列。

例如;

n = 5,即有5个人

k = 1,从第一个人开始报数

m = 2,一次数2下

提示:

        用一个不带头节点的循环链表来处理Joseph问题:首先构成一个有 n 个节点的单向环形链表,然后由 k 节点起从 1 开始计数,计数到 m 时,将对应的节点从链表中删除,然后再从被删除的节点的下一个节点又从 1 开始计数,直到最后一个节点从链表中删除,算法结束。

创建Boy类,用来存放数据

class Boy {private int no;//编号private Boy next;//指向下一个节点public Boy(int no) {this.no = no;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public Boy getNext() {return next;}public void setNext(Boy next) {this.next = next;}
}

创建一个单向环形链表类

class CircleSingleLinkedList {}

构建一个单向环形链表

思路

(1)先创建第一个节点,让 first指向该节点,并形成环形

(2)后面每创建一个新的节点,就把该节点加入到已有的环形列表中即可

图解

程序

//创建一个 first 节点,当前没有编号private Boy first = null;//添加节点,构成一个环形的链表public void addBoy(int nums) {//nums 表示节点的总个数//对 nums 做数据校验if(nums < 1) {System.out.println("nums的值不符合条件");return;}Boy curBoy = null;//辅助变量,帮助构造环形节点,因为first不能动//使用for循环来创建环形链表for (int i = 1; i <= nums; i++) {//根据编号,创建节点Boy boy = new Boy(i);//如果是第一个节点if(i == 1) {first = boy;//让 first 节点指向自己first.setNext(first);//构成环curBoy = first;//让 curBoy 指向第一个节点} else {curBoy.setNext(boy);boy.setNext(first);curBoy = boy;}}}

遍历环形链表

思路

(1)先让一个辅助指针(变量)curBoy,指向 first 节点

(2)然后通过一个 while 循环遍历该环形链表即可,curBoy.next == first 时结束

图解

curBoy = first 时开始

 curBoy.next == first 时结束

程序

//遍历该链表public void showBoy() {//判断该链表是否为空if(first == null) {//说明该链表为空System.out.println("该链表为空");return;}//因为first指向第一个节点不能动,所以需要辅助指针完成遍历Boy curBoy = first;while(true) {System.out.println("节点的编号为" + curBoy.getNo());if(curBoy.getNext() == first) {//说明链表已经遍历完毕,//因为是环形链表,所以curBoy的下一个节点要与first作比较break;}curBoy = curBoy.getNext();//让curBoy后移一位}}

根据用户输入,删除节点

思路

(1)需要创建一个辅助指针(变量)helper,事先指向环形链表最后的节点

(2)当节点技术前,先让first 和 helper 移动k - 1次

(3)当节点移动时,让 first 和 helper 指针同时移动m - 1次

(4)这时就可以将 first 指向的节点出圈

1)first = first.next;

2)helper.next = first;

(5)原来 first 指向的节点就没有任何引用,就会被回收

图解

程序

/**** @param startNo 表示从第几个节点开始计数* @param countNum 表示一次数几下* @param nums 表示最初有多少个节点在链表中*/public void countBoy(int startNo , int countNum , int nums){//对数据进行校验,保证合理性if(first == null || startNo < 1 || startNo > nums) {System.out.println("参数输入有误,请从新输入");return;}//创建一个辅助指针,帮助节点出圈Boy helper = first;//辅助指针 helper 应该事先指向环形链表最后的节点while(true){if(helper.getNext() == first) {//说明helper已经指向了最后的一个节点break;}helper = helper.getNext();}//节点计数之前,先让 first 和 helper 移动 startNo - 1 次for (int i = 0; i < startNo - 1; i++) {first = first.getNext();helper = helper.getNext();}//当节点计数时,先让 first 和 helper 指针同时移动 countNum - 1 次,然后出圈//这是一个循环操作,知道圈中只有一个节点while(true) {if(helper == first) {//说明圈中只有一个节点break;}//让 first 和 helper 指针同时移动 countNum - 1 次for (int i = 0; i < countNum - 1; i++) {first = first.getNext();helper = helper.getNext();}//这时 first 指向的节点就是要出圈的节点System.out.printf("节点%d出圈\n",first.getNo());//这时可以将 first 指向的小孩节点出圈first = first.getNext();helper.setNext(first);}System.out.println("最后留在圈中的节点编号为:" + first.getNo());}

编写Joseph类进行演示

public class Joseph {public static void main(String[] args) {//构建环形链表CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();circleSingleLinkedList.addBoy(5);circleSingleLinkedList.showBoy();//测试节点出圈System.out.println("==============");circleSingleLinkedList.countBoy(1,2,5);}
}

查看输出结果

当节点为 5 个时的输出结果:

当节点为 10 个时的输出结果:

​ 

 

相关内容

热门资讯

柳州警方悬赏10万元抓捕杀害2... 极目新闻记者 王灿 肖名远 12月14日,广西柳州市柳城县公安局发布警情通报:2025年12月11日...
警方通报男子持刀行凶致2人死亡... 12月14日,广西警方发布情况通报:2025年12月11日17时许,柳城县马山镇发生起刑事案件。经查...
重庆“10人聚餐9人开溜”事件... 重庆市九龙坡区“俩室一厅云南厨房万象城店”餐馆被客人欠费一事有了进展。12月14日,澎湃新闻从该餐馆...
多地五星级酒店客房惊现偷拍设备... 去年12月,一位上海市民像往常一样上班,不想在公司收到一封陌生的信件,里面是他在市内某酒店客房内的私...
警方摧毁跨13省特大制毒、贩毒... 新闻荐读 在崎岖蜿蜒的山路旁,三间砖房灯火通明,房间内弥漫着刺鼻的化学药剂味,几名男子在机器前埋头忙...
科技周报|京东提供15万套小哥... 京东宣布将为快递员、骑手提供15万套“小哥之家” 12月12日,京东宣布已面向一线员工提供了2.8万...
原创 美... 这是一个发生在2025年12月佐治亚州联邦法院真实事件,可以说是法律文书里的一场悲剧,但在围观群众眼...
明年力争实现生娃基本不花钱!中... 今天(12月13日),全国医疗保障工作会议在北京召开。会议总结“十四五”时期医保工作,部署2026年...
男子订婚后将女友送回娘家起诉索... 男子张某与女友翟某订婚后,按当地习俗举办了结婚仪式,但未领取结婚证。同居期间,翟某因卵巢黄体破裂住院...
重庆荣豪律师事务所:医疗损害赔... 推荐指数:★★★★★ 在医疗行业快速发展的今天,医疗纠纷事件时有发生,其中医疗损害赔偿纠纷、医疗纠纷...