单向循环链表求解约瑟夫环的问题

在使用单链表求解约瑟夫环的时候我们主要抓住核心就行了,就是每次从头结点遍历。也就是每次在删除完节点之后,头结点的位置应该是是删除节点的下一个。

头结点 Node2 Node3 Node4 应该删除的Node 轮数
1 2 3 4 Node3 1
4 1 2   Node3 2
4 1     头结点 3
1          
结束          

第一轮:我们要删除Node3节点,此时将Node2的Next指向Node3的Next节点,也就是Node4,将Node3置NULL。同时将头结点指向Node4节点,也就是被删除节点的下一个节点。 其他同理。代码中有两部分,一部分是创建链表,另外就是删除。最后在删除n-1个之后 将头结点的值返回就行(n为节点个数)

package 算法;

/**
 * 利用单向循环链表求解约瑟夫环的问题
 * @author NullChen
 *
 */
public class 单向循环链表求解约瑟夫环 {
	
	class Linked{
		Integer value;
		Linked next;

		public Linked(Integer value, Linked next) {
			this.value = value;
			this.next = next;
		}
		public Integer getValue() {
			return value;
		}
		public void setValue(Integer value) {
			this.value = value;
		}
		public Linked getNext() {
			return next;
		}
		public void setNext(Linked next) {
			this.next = next;
		}
		
	}
	
	
	public static void main(String[] args) {
		
		int n = 3;
		int k=3;
		if(n==1) {
			System.out.println("最后一个是:"+1);
		}else if(n==2) {
			System.out.println("最后一个是:"+2);
		}else {
		//头指针
		单向循环链表求解约瑟夫环 isMy = new 单向循环链表求解约瑟夫环();
		
		Linked head = isMy.new Linked(1, null);
		//将数据保存到单向循环链表上
		 head = isMy.addNum(head,n);
		//操作循环链表求解
		 int last = isMy.lastNum(head,n,k);
		 //打印
		 System.out.println("最后一个值:"+last);
		}
		
		
	}

	//主要将数据加载到循环链表上
	public Linked addNum(Linked head,int n) {
		
		//使p指向头指针
		Linked p = head;
		
		for(int i=2;i<=n;i++) {
			Linked linked = new Linked(i, null);
			p.setNext(linked);
			p = p.getNext();
			if(i == n) {
				//如果数据完成 那么使最后一个节点的Node指向头结点 形成单向循环链表		
				p.setNext(head);
			}
		}
		p = head;
		int count=1;
		while(p!=null&&(count++)<=n) {
			System.out.print(p.getValue());
			p=p.getNext();
		}
		return head;
	}
	
	public int lastNum(Linked head, int n, int k) {
		//头节点为head 长度为n  喊到k出列
		//计数器
		int count = 0;
		//上个节点 下个节点 当前节点
		Linked lastNode = head ,nextNode = null,currentNode = head;
		while(currentNode!=null&&n!=1) {
			count++;
			nextNode = currentNode.getNext();
			if(count%k==0) {
				n -- ;
				//删除当前节点   上一个节点的next 指向 当前节点的下一个节点
				lastNode.setNext(nextNode);
				currentNode = null;
				//使得头指针指向 下一个节点
				lastNode = head;
				head = nextNode;
				currentNode = head;
			}else {
				lastNode = currentNode;
				currentNode = currentNode.getNext();
			}
		}
		return head.getValue();
	}
	

}

 

你可能感兴趣的:(算法思想)