单向环形链表-约瑟夫

构建思路

  1. 先创建一个节点,让first指向该节点,并形成环形
  2. 后面当我们每创建一个新的节点,就把该节点加入到已有的环形链表中即可
    节点类:
public class Boy {
    private int no;
    private String name;
    private Boy next;
    ...
    }

增加

环类及增加方法:

public class CircleSingleLinkedList {
    //创建一个first节点
    private Boy first = null;
    private Boy curBoy = null ;//辅助指针,帮助构建环形链表
    //添加n个boy
    public void addBoy(int num){
        if(num<1){
            System.out.println("sums值不正确");
            return;
        }

        for(int i = 1;i<=num;i++){
            Boy boy = new Boy(i,String.valueOf(i));
            if(i == 1){
                first = boy;
                first.setNext(first);
                curBoy = first;
                continue;
            }
            curBoy.setNext(boy);
            boy.setNext(first);
            curBoy = boy;
        }
    }
    //添加对象boy
    public void addABoy(Boy boy){
        if(first == null){
            first = boy;
            first.setNext(first);
        }
        else {
            curBoy = first.getNext();
            while (curBoy.getNext()!=first)
                curBoy = curBoy.getNext();
            curBoy.setNext(boy);
            boy.setNext(first);
        }
    }
    ...
}

遍历环形链表

  1. 先让一个辅助指针(变量)curBoy,指向first节点
  2. 通过一个while循环遍历该环形链表,当curBoy == first时结束
//遍历当前的环形链表
public void showBoy(){
    if(first == null){
        System.out.println("无小孩");
        return;
    }
    Boy curBoy = first;
    while (true){
        System.out.println(curBoy.toString());
        if(curBoy.getNext() == first)
            break;
        curBoy = curBoy.getNext();
    }
}

报数出环

  1. 先让一个辅助指针(变量)helper指向最后一个节点
  2. first跟helper一起移动,first指向被删除节点,helper指向上一个
  3. 删除时:first = first.next() ; helper.next() = first;
  4. 当helper = first 时只剩一个,循环结束
//按顺序出圈
/**
 *
 * @param startNo 表示从第几个小孩开始数数
 * @param countNum 表示数几下
 * @param nums 表示最初有几个小孩
 */
public void countBoy(int startNo,int countNum,int nums){
    //对数据进行校验
    if(first == null || startNo < 1 || startNo > nums){
        System.out.println("输入有误,请重新输入");
        return;
    }
    //创建辅助指针,帮助小孩出圈
    Boy helper = first;
    //
    while (helper.getNext() != first) {
        helper = helper.getNext();
    }
    //小孩报数,让first和helper移动 startNo-1 次
    for(int i = 0;i<startNo-1;i++){
        first= first.getNext();
        helper = helper.getNext();
    }

    //开始报数循环
    while (helper != first){
        for (int i =0; i<countNum-1;i++){
            first= first.getNext();
            helper = helper.getNext();
        }
        System.out.println(first.toString());
        first = first.getNext();
        helper.setNext(first);
    }
    System.out.println(first.toString());
}
/**
 * 自己写的,没有辅助变量
 * @param startNo 表示从第几个小孩开始数数
 * @param countNum 表示数几下
 * @param nums 表示最初有几个小孩
 */
public void countBoyWithFirst(int startNo,int countNum,int nums){
    //对数据进行校验
    if(first == null || startNo < 1 || startNo > nums){
        System.out.println("输入有误,请重新输入");
        return;
    }

    // 让first移动到first的前一个
    for(int i =0;i<nums-1;i++)
        first = first.getNext();

    // 移动到开始位置
    for(int i =0;i<startNo-1;i++){
        first = first.getNext();
    }

    //开始报数循环
    while (first.getNext()!=first){
        for (int i =0; i<countNum-1;i++){
            first= first.getNext();
        }
        System.out.println(first.getNext());
        first.setNext(first.getNext().getNext());
    }
    System.out.println(first);
}
发布了45 篇原创文章 · 获赞 1 · 访问量 563

猜你喜欢

转载自blog.csdn.net/BNMZY/article/details/104889130
今日推荐