java循环链表实现约瑟夫环问题

说明:测试程序,输入一个数字构成约瑟夫环,再输入另外一个数字来以此数数。最后剩下的那个人为生存者,或者猴子大王。

学习笔记:1 约瑟夫环在删除过程中要动态改变current以及prior的值。

<pre name="code" class="java">package com.marthevin.linkedlist;

import java.util.Scanner;

public class YuesefuCircleTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		   System.out.println("Input a num to create a circle....");
           Scanner  scanner = new Scanner(System.in);
           int N = scanner.nextInt();
           System.out.println("Input a num to count...");
           int M = scanner.nextInt();
           int[] array = new int[N];
           for(int i=1;i<=N;i++)
           {
        	   array[i-1] =i;
           }
           
          YuesefuCircle circle = new YuesefuCircle();
          circle.createCircleByArr(array);
          circle.deleteNodeByDivident(M);
          circle.printCircle();
          
	}

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

class YuesefuCircle{
	NodeC head,tail;
	int count = 0;  //count控制最终的循环是否继续
	int divident = 0; //表示输入几个数之后删除节点
	
	public NodeC deleteNodeByDivident(int div)
	{
		this.divident = div;
		NodeC current = head, prior = head;
		while(this.count>1)
		{
			for(int i=1;i<div;i++)
			{
				prior = current;
				current = current.next;
			}
			//删除current
			if(current==head) //current 为 head 删除head  
			{
				head = head.next;
				current = head;
			}else if(current==tail) //current为tail 删除tail 
			{
				tail = prior;
				tail.next = head;
				current = head;
			}else{
				prior.next = current.next;
				current = prior.next;
			}
			count--;
		}
		return head;
	}
	
	public int createCircleByArr(int[] arr)
	{
		int number = 0;
		int length = arr.length;
		for(int i=1;i<=length;i++)
		{
			NodeC newnode = new NodeC(arr[i-1]);
			if(i == 1)
			{
				head = newnode;
				tail = newnode;
			}else{
				tail.next = newnode;
				tail = newnode;
				newnode.next = head;
			}
			number++;
			count++;
		}
		return number;
	}
	
	public void printCircle()
	{
		if(head==null)
		{
			System.out.println("null list...");
		}
		System.out.println("count= "+count+"\r\n"+"person left= "+head.data);
	}
	
	public YuesefuCircle()
	{
		head = tail = null;
	}
	
	
	
}


 

约瑟夫环问题是一个经典的问题,可以使用双向循环链表来解决。具体的思路可以按照以下步骤来实现: 1. 创建一个双向循环链表,并添加指定数量的节点 2. 定义一个计数器,用于计数当前报数的人数 3. 从链表的头部开始遍历,每次遍历到一个节点时,计数器加1,如果计数器的值等于指定的报数值,就将该节点从链表中删除,并将计数器重置为1 4. 当链表中只剩下一个节点时,即为最后的获胜者 下面是一个 Java 实现的示例代码: ```java public class JosephCircle { // 定义双向链表节点 private static class Node<T> { T item; Node<T> prev; Node<T> next; Node(T item, Node<T> prev, Node<T> next) { this.item = item; this.prev = prev; this.next = next; } } public static void main(String[] args) { int n = 7; // 总人数 int m = 3; // 报数值 Node<Integer> head = null; Node<Integer> tail = null; // 创建双向链表 for (int i = 1; i <= n; i++) { if (head == null) { head = new Node<>(i, null, null); tail = head; head.prev = tail; tail.next = head; } else { Node<Integer> node = new Node<>(i, tail, head); tail.next = node; tail = node; head.prev = tail; } } // 从头节点开始遍历链表 Node<Integer> current = head; int count = 1; while (current.next != current) { count++; if (count == m) { count = 1; System.out.println("删除节点:" + current.item); current.prev.next = current.next; current.next.prev = current.prev; current = current.next; } else { current = current.next; } } System.out.println("获胜者:" + current.item); } } ``` 输出结果: ``` 删除节点:3 删除节点:6 删除节点:2 删除节点:7 删除节点:5 删除节点:1 获胜者:4 ``` 以上就是使用 Java 双向循环链表求解约瑟夫环问题的示例代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值