java创建环形链表,五、单项环形链表,

这篇博客介绍了一个使用Java解决约瑟夫环问题的方法,通过创建一个单项环形链表来模拟过程。首先创建含有n个节点的环形链表,然后从指定节点开始按m的步长报数,数到m的节点将被删除,直至所有节点出列。提供的代码示例展示了如何构建链表、遍历链表以及执行约瑟夫环算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

五、单项环形链表,

单项环形链表

约瑟夫环问题

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

思路:

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

代码示例:

public class Josepfu {

public static void main(String[] args) {

SingleCircleLinkedList singleCircleLinkedList = new SingleCircleLinkedList();

singleCircleLinkedList.Josepfu(1, 2, 5);

}

}

//创建单项环形链表

class SingleCircleLinkedList {

//创建一个first节点,当前没有编号

private Node first;

/**

* @param nums 为环形链表添加几个节点

*/

public void createSingleCircleLinkedList(int nums) {

if (nums < 1) {

System.out.println("nums值不正确");

return;

}

Node curNode = null;

for (int i = 1; i <= nums; i++) {

//根据编号创建节点

Node node = new Node(i);

if (i == 1) {

first = node;

first.setNext(first);//构成环

curNode = first;//让curNode指向第一个节点

} else {

curNode.setNext(node);

node.setNext(first);

curNode = node;

}

}

}

/**

* 遍历当前环形链表

*/

public void list() {

if (first == null) {

throw new RuntimeException("链表为空!");

}

Node curNode = first;

while (true) {

System.out.println(curNode);

if (curNode.getNext() == first) {

break;

}

curNode = curNode.getNext();

}

}

/**

* 根据用户的输入来完成约瑟夫环问题

*

* @param startNo 表示从编号几开始数

* @param countNum 表示数几下

* @param nums 表示最初有几个人

*/

public void Josepfu(int startNo, int countNum, int nums) {

if (nums < 1 || startNo < 1 || startNo > nums) {

throw new RuntimeException("参数输入有误!");

}

createSingleCircleLinkedList(nums);

Node pre = first;

//使pre指向first节点的前一个节点

while (true) {

if (pre.getNext() == first) {

break;

}

pre = pre.getNext();

}

//使first和pre先移动到一开始报数的人那里

for (int i = 0; i < startNo - 1; i++) {

first = first.getNext();

pre = pre.getNext();

}

//当第一个人开始报数时,让first和pre指针同时开始移动countNum-1此,然后first指向的节点出圈

while (true) {

if (first == pre) {

break;

}

for (int i = 0; i < countNum - 1; i++) {

first = first.getNext();

pre = pre.getNext();

}

//这时first指向的节点就是要出圈的节点

System.out.println(first);

first = first.getNext();

pre.setNext(first);

}

//退出循环后,圈中就只剩下一个节点了。

System.out.println(first);

}

}

class Node {

private int no;

private Node next;

public Node(int no) {

this.no = no;

}

public int getNo() {

return no;

}

public void setNo(int no) {

this.no = no;

}

public Node getNext() {

return next;

}

public void setNext(Node next) {

this.next = next;

}

@Override

public String toString() {

return "Node{" +

"no=" + no +

'}';

}

}

相关文章暂无相关文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值