尚硅谷Java数据结构学习记录7-约瑟夫环的实现

主要难点:

1.游戏规则的理解。包括从第几个开始,喊的数是几,以及初始小孩个数。

从第几个开始:可以理解为fisrt转到了开始点(相应的与first连接的点helper也转到了与开始点连接的那个点)

喊的数是几:这个是小孩出圈的位置,即从开始点循环K-1次,相连接的点同步

此时小孩出圈,first = first.next;helper.next = first;

初始小孩个数:构成约瑟夫环

思路;约瑟夫环需要有一个指针指向与first相连接的节点,这样保证当节点删除的时候,最后一个节点仍然能找到新的节点并再次连接成环

package datacode;

public class Josepfu {
	
	static class Boy{
		private int no; //编号
		private Boy next;
		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;
		}
		public Boy(int no) {
			this.no = no;
		}


	
	}
	
	//创建环形单向链表
	static class CicleSingleLinkList{
		//创建一个first节点,当前没有编号
		private Boy first = new Boy(-1);
		//添加小孩节点,构建成一个环形的链表
		public void addBoy(int nums) {
			//nums 需要进行检验
			if(nums < 2) {
				System.out.println("nums的值不正确");
				return;
			}
			Boy curBoy = null; //辅助节点
			//使用for循环创建环形链表
			for(int i = 1; i <= nums;i++) {
				Boy boy = new Boy(i);
				if(i == 1) {
					first = boy;
					curBoy = first; //curBoy指向第一个小孩
				}else {
					 curBoy.setNext(boy);
					 boy.setNext(first);
					 curBoy = boy;
				}
			}
		}
		
		//遍历环形链表
		public void list() {
			//链表是否为空
			if(first == null) {
				System.out.println("链表为空");
				return;
			}
			Boy curBoy = first;
			while(true) {
				System.out.printf("Boy的编号%d\n",curBoy.no);
				if(curBoy.getNext() == first) {
					System.out.println("已经遍历结束\n");
					break;
				}
				curBoy = curBoy.getNext();
			}
		}
		
		//删除
		/*
		 * 先将first 和 helper移动k-1次
		 */
		public void delete(int startNo,int countNum,int nums) {
			//从哪个小孩开始数  数几下 最初有几个小孩
			if(first == null||startNo < 1|| startNo > nums) {
				System.out.println("参数有误,请重新输入");
				return;
				}
			Boy helper = first;
			while(true) {
				if(helper.next == first)
					break;
				helper = helper.getNext();
			
			}
			//开始位置
			for(int i = 0; i < startNo -1; i++) {
				first = first.getNext();
				helper = helper.getNext();
			}
			
			//循环出圈操作
			while(true) {
				if(helper.no == first.no)
					break;
				//让first和helper同时移动很多次
				for(int i =0; i < countNum-1;i++) {
					first = first.getNext();
					helper = helper.getNext();
				}
				//此时first所在位置要出圈
				System.out.printf("要出圈的小孩是%d\n",first.getNo());
				first = first.next;
				helper.next = first;
				//helper.setNext(first);
			}
			System.out.printf("最后一位是%d",helper.getNo());
			
			
		}
	}	
		
	

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		CicleSingleLinkList circlesinglelinklist = new CicleSingleLinkList();
		circlesinglelinklist.addBoy(5);
		circlesinglelinklist.list();
		//没有考虑到一种情况  为空,即在函数中最后一个参数没有用到,除判断外
		circlesinglelinklist.delete(1, 2, 5);
	}

}

 

做一门精致,全面详细的 java数据结构与算法!!!让天下没有难学的数据结构,让天下没有难学的算法,不吹不黑,我们的讲师及其敬业,可以看到课程视频,课件,代码的录制撰写,都是在深夜,如此用心,其心可鉴,他不掉头发,谁掉头发???总之你知道的,不知道的,我们都讲,并且持续更新,走过路过,不要错过,不敢说是史上最全的课程,怕违反广告法,总而言之,言而总之,这门课你值得拥有,好吃不贵,对于你知识的渴求,我们管够管饱话不多说,牛不多吹,我们要讲的本门课程内容:稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表约瑟夫问题、栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树和B*树)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值