ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数据结构(五)-环形链表及约瑟夫问题

2020-09-18 08:02:00  阅读:221  来源: 互联网

标签:getNext helper int 约瑟夫 链表 数据结构 startNo first


一、单向环形链表的应用场景(约瑟夫问题)

Josephu 问题为:设编号为1,2, ... n 的 n 个人坐成一圈,约定从编号为 k(n≥k≥1) 的人开始报数,数到 m 的那个人出列,她的下一位又从 1 开始报数,数到 m 的那个人又出列,以此类推,直到所有人出圈为止,因此形成一个出圈编号的序列

二、单向链表的示意图

三、创建环形链表图解

创建环形链表代码实现

// 创建单向环形链表
class SingleCircularLinkedList{
	
	// 初始化一个头节点
	Girl first = null;
	
	// 添加数据到链表中
	public void add(int num) {
		// 校验参数
		if(num < 1) {
			System.out.println("您输入的小孩个数小于1,不能创建环形链表");
		}
		// 定义临时指针
		Girl curGirl = first;
		for(int i = 1; i <= num; i++) {
			Girl girl = new Girl(i);
			
			if(i == 1) { // 说明是第一个节点
				first = girl;
				first.setNext(first);
				curGirl = first;
			}else {
				curGirl.setNext(girl);
				curGirl = girl; // curGirl 后移
				curGirl.setNext(first); // 形成闭环
			}
		}
	}
	
	// 遍历链表
	public void list() {
		// 判断链表是否为空
		if(first == null) {
			System.out.println("当前链表为空");
			return;
		}
		// 定义临时指针
		Girl curGirl = first;
		while(true) {
			System.out.printf("小孩编号为 %d \n", curGirl.getNo());
			if(curGirl.getNext() == first) {
				break;
			}
			curGirl = curGirl.getNext();
		}
	}
}

// 创建节点类
class Girl {

	private int no;
	private Girl next;

	public Girl(int no) {
		super();
		this.no = no;
	}

	public int getNo() {
		return no;
	}

	public void setNo(int no) {
		this.no = no;
	}

	public Girl getNext() {
		return next;
	}

	public void setNext(Girl next) {
		this.next = next;
	}
}

四、约瑟夫问题图解

补充,设置 helper 节点的思路来源于单向链表删除节点时,指针始终指在当前节点的前一位,cur.next = cur.next.next
代码实现

	// 约瑟夫问题
	public void joseph(int startNo, int countNum, int nums) {
		// 参数校验
		if(startNo < 1 || countNum > nums || nums < 1) {
			System.out.println("输入的参数有误");
			return;
		}
		// 定义临时指针
		Girl helper = first;
		// 让helper移动到first的上一个节点的位置,让first指针移动到startNo处(移动startNo - 1次)
		while(true) {
			if(helper.getNext() == first) {
				break;
			}
			helper = helper.getNext();
		}
		
		for(int i = 0; i < startNo - 1; i++) {

			first = first.getNext();
			helper = helper.getNext();
		}
		
		// 让first和helper同时移动countNum - 1次,小孩出圈
		while(true) {
			if(helper == first) { // 条件成立说明圈中只有一个小孩
				break;
			}
			for(int i = 0; i < countNum - 1; i++) {
				first = first.getNext();
				helper = helper.getNext();
			}
			// 小孩出圈操作
			System.out.printf("出圈的小孩为  %d 号\n", first.getNo());
			first = first.getNext();
			helper.setNext(first);
		}
		// 输出圈中留下的lucky girl
		System.out.printf("留在圈中的 lucky girl 为  %d 号\n", first.getNo());
	}

标签:getNext,helper,int,约瑟夫,链表,数据结构,startNo,first
来源: https://www.cnblogs.com/wsilj/p/13689060.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有