java单链表解决约瑟夫环问题

但链表类节点数据没有使用引用类型,使用int类型表示

单链表类:

package Class.LinkList;

public class LinkList {
    public Node head;
    /*
        链表:
            1. head是一个在链表外的Node对象,头节点不算在链表内,且头节点不算在长度内
            2. 链表其实是多个Node类型的数据链接一起
            3. 链表的最后一个节点的nextNode属性为null
     */

    // 构造方法一:链表为空链表,只有一个头节点
    // 因为是int类型, 头指针指向节点其实有默认值0
    public LinkList() {
        head = new Node();
    }

    // 构造方法二:数组传值,形成单链表
    // 以数组形式传值. 这里是int数组
    // 没有考虑传值数组内值为空的情况(因为为Int类型)
    public LinkList(int[] arr) {
        this();
        Node rear = head;   // 尾指针,便于数组传值
        for (int i = 0; i < arr.length; i++) {
            // rear.toNextNode() = new Node(arr[i], null);
            // 一开始把nextNode设为private, 但这样会报错???
            rear.nextNode = new Node(arr[i], null);
            rear = rear.nextNode;
        }
    }

    // 构造方法三:链表内有一个Node节点
    public LinkList(int m) {
        head = new Node(0, null);
        head.nextNode = new Node(m, null);
    }

    public boolean isEmpty() {
        return head.nextNode == null;
    }

    // 遍历链表,直到rear指针指向null
    public int LinkLength() {
        Node rear = head;
        int length = 0;
        while (rear.nextNode != null) {
            length++;
            rear = rear.nextNode;
        }
        return length;
    }

    // 获得第n个节点的值,同样需要遍历
    /*
        假设需要获得第2个节点的值,需要把rear指针指向第二个节点
        即需要遍历2次 --> 获得第n个节点的值需要遍历n次
     */
    public int getInfo(int n) {
        Node rear = head;
        for (int i = 0; i < n; i++) {
            rear = rear.nextNode;
        }
        return rear.getInt();
    }

    // 输出单向链表
    public void showAllNum() {
        Node rear = head;
        for (int i = 1; i <= this.LinkLength(); i++) {
            System.out.print(this.getInfo(i) + "\t");
        }
        System.out.println("");
    }



}

约瑟夫环类和主类:

package Class.Josephus;

import Class.LinkList.LinkList;
import Class.LinkList.Node;

public class Josephus_LinkList {
    private LinkList linkList;   // 单链表属性

    public Josephus_LinkList(LinkList linkList) {
        this.linkList = linkList;
    }

    public int getSurvivor(int start, int distance) {
        // front指针指向待删除节点的前驱节点
        Node front = linkList.head;
        // front指针初始化
        for (int i = 0; i < start; i++) {
            front = front.nextNode;
        }
        while (linkList.LinkLength() > 1) {
            // 指针移动,循环用于到达前驱节点
            for (int i = 0; i < distance - 1; i++) {  // distance = 3, 遍历 2 次
                front = front.nextNode;
                // 如果front指向null, 则指向头节点
                if (front == null) {
                    front = linkList.head.nextNode;
                }
            }
            // 如果front指针指向最后一个节点,则删除链表第一个节点
            if (front.nextNode == null) {
                front = linkList.head;
            }
            // 删除节点
            front.nextNode = front.nextNode.nextNode;
            // front.nextNode = this.nextNode(linkList, this.nextNode(linkList, front));
            // front.nextNode会陷入死循环(front指向最后一个节点)
        }
        return linkList.head.nextNode.getInt();
    }

    /*
    public Node nextNode(LinkList linkList, Node node) {
        node = node.nextNode;
        if (node == null) {
            node = linkList.head.nextNode;
        }
        return node;
    }

     */
}

class Start {
    public static void main(String[] args) {
        // 创建单链表
        int[] arr = {10, 20, 30, 40, 50};
        LinkList linkList = new LinkList(arr);
        linkList.showAllNum();
        //
        Josephus_LinkList josephusLinkList = new Josephus_LinkList(linkList);
        int survivor = josephusLinkList.getSurvivor(1, 3);
        System.out.println(survivor);
    }
}

运行结果:

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值