1. 节点构建
//构建节点
class Item{
private int no;
private Item next;
public Item(int no) {
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public Item getNext() {
return next;
}
public void setNext(Item next) {
this.next = next;
}
@Override
public String toString() {
return "item [no=" + no + "]";
}
}
2、约瑟夫链表构建
- 代码
//构建josephu链表
class JosephuLinkList{
//创建first指针,用于指向第一个节点
Item first = null;
//添加nums个节点
public void add(int nums) {
//对nums进行校验
if(nums < 1) {
System.out.println("添加个数不正确!");
}else {
//辅助指针,用于指向当前的节点
Item curItem = null;
for (int i = 1; i <= nums; i++) {
Item item = new Item(i);
if(i == 1) {//第一次添加
first = item;
item.setNext(item);
curItem = item;
}else {
curItem.setNext(item);
item.setNext(first);
curItem = item;
}
}
}
}
//遍历
public void list() {
if(first == null) {
System.out.println("尚无节点!");
return;
}
Item curItem = first;
while (true) {
System.out.printf("打印环装链表数据:item的no:%d\n",curItem.getNo());
if(curItem.getNext() == first) {
break;
}else {
curItem = curItem.getNext();
}
}
}
/**
*
* @param startItem 第几个开始
* @param count 树几下
* @param nums 一共几个人
*/
public void countItems(int startItem,int count,int nums ) {
//首先对数字进行校验
if(startItem < 1||startItem > nums||nums < 1) {
System.out.println("输入格式不正确!");
return;
}
//定义辅助变量,指向环状链表尾部
Item helper = first;
while(true) {
if(helper.getNext() == first) {
break;
}
helper = helper.getNext();
}
//第几个开始 firse和helper 一起移动(startItem-1)下
for(int i = 0; i < startItem-1; i++) {
first = first.getNext();
helper = helper.getNext();
}
//开始循环数数并打印
while(true) {
if(first == helper) {
break;
}
//数count下 firse和helper 一起移动(count-1)下
for(int i = 0; i < count-1; i++) {
first = first.getNext();
helper = helper.getNext();
}
//打印节点数据并删除节点
System.out.printf("josephu打印数据:%d\n",first.getNo());
//并删除节点
first = first.getNext();
helper.setNext(first);
}
//打印最后一个节点
System.out.printf("josephu打印数据:%d\n",first.getNo());
}
}
- 思路
1、首先定义输入参数:一共几个同学nums,从第几个开始startItem,每次数几下count;
2、定义辅助变量/指针:helper指向尾部,即first指针的前一个节点,作用:用于删除节点(helper指向待删除节点的前一个节点)
3、先让helper和firse指针同时移动(startItem-1)下,到开始同学的位置。
4、开始玩游戏,让同学数count下,同时first和helper指针移动(count-1)下,然后打印first指针指向节点的信息,然后删除first指针指向的节点:
first = first.next;
helper.next = first;
5、first指向的同学继续玩游戏,重复第四步骤,直到剩下最后一个同学。
3. 测试
- 代码:
public class JosephuLinkListDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
JosephuLinkList josephuLinkList = new JosephuLinkList();
josephuLinkList.add(15);
josephuLinkList.list();
josephuLinkList.countItems(1,2,15);
}
}
- 测试结果:
打印环装链表数据:item的no:1
打印环装链表数据:item的no:2
打印环装链表数据:item的no:3
打印环装链表数据:item的no:4
打印环装链表数据:item的no:5
打印环装链表数据:item的no:6
打印环装链表数据:item的no:7
打印环装链表数据:item的no:8
打印环装链表数据:item的no:9
打印环装链表数据:item的no:10
打印环装链表数据:item的no:11
打印环装链表数据:item的no:12
打印环装链表数据:item的no:13
打印环装链表数据:item的no:14
打印环装链表数据:item的no:15
josephu打印数据:2
josephu打印数据:4
josephu打印数据:6
josephu打印数据:8
josephu打印数据:10
josephu打印数据:12
josephu打印数据:14
josephu打印数据:1
josephu打印数据:5
josephu打印数据:9
josephu打印数据:13
josephu打印数据:3
josephu打印数据:11
josephu打印数据:7
josephu打印数据:15