博客搬家啦,更多干货 https://blog.csdn.net/qq_2816...

image.png

import java.util.ArrayList;

/**
 * 循环链表
 */
public class CycleList {

    public int size;
    public Node head;

    /**
     * 解决约瑟夫问题
     */

    /**
     * 链表头插入
     * @param val
     */
    public void insertHead(Object val){
        Node node = new Node(val);
        // 如果存在表头
        node.next = head;
        head = node;

    }

    /**
     * 指定位置插入
     * @param val
     * @param pos
     */
    public void insertNth(Object val, Integer pos){
        // 如果是头节点
        if(pos == 1){
            insertHead(val);
        }else{
            Node node = new Node(val);
            Node cur = head;
            for (int i=2 ; i<pos; i++){
                cur = cur.next;
            }
            node.prev = cur;
            node.next = cur.next;
            cur.next = node;
            // 尾节点
            if(node.next == null){
                node.next = head;
                head.prev = node;
            }
        }
        size++;
    }

    /**
     * 打印整个链表
     */
    public void printList(){
        Node node = head;
        System.out.println("头节点:"+node.val);
        while (node.next != head && node.next != null){
            System.out.println(node.val);
            node = node.next;
        }
        System.out.println("尾节点:"+node.val);
//        System.out.println("尾节点的next:"+node.next.val);
    }

    /**
     * 打印单个节点的值
     * @param pos
     */
    public Object getNode(Integer pos){
        Node node = head;
        for (int i = 1; i<pos; i++){
            node = node.next;
        }
        return node.val;
    }

    /**
     * 删除头节点
     */
    public void deleteHead(){
        head.next.prev = head.prev;
        head = head.next;
    }

    /**
     * 删除指定位置的节点
     * @param pos
     */
    public void deleteNode(Integer pos){
        if(pos == 1){
            deleteHead();
        }else{
            Node cur = head;
            for (int i = 2; i<pos; i++){
                cur = cur.next;
            }
            cur.next = cur.next.next;
            cur.next.prev = cur;
        }
        size--;
    }

    /**
     * 约瑟夫问题
     * @param m
     * @return
     */
    public ArrayList Joseph(Integer m){
        Node cur = head;
        ArrayList arrayList = new ArrayList();
        // 输入m, 每隔m-1杀一个, 找到了next,那就是每 循环 m-2 杀一个
        while (size > 1){
            for (int i = 0; i< m-2; i++){
                cur = cur.next;
            }
            arrayList.add(cur.next.val);
            // 只剩下最后两个人的时候,直接另当前值等于head,避免死循环
            if(size == 2){
                cur.next = null;
                cur.prev = null;
                head = cur;
                break;
            }else{
                cur.next = cur.next.next;
                cur.next.prev = cur;
            }
            size--;
            cur = cur.next;
        }
        return arrayList;
    }



    public Integer getSize(){
        return size;
    }

    /**
     * 节点
     */
    public class Node{
        public Node next;
        public Object val;
        public Node prev;

        Node(Object val){
            this.val = val;
        }
    }
}

image.png

需要注意的点就是,避免循环链表的死循环,自身指向自身

其实还有很多其他解法,普通的循环链表也可以

头节点的处理有些问题,后续更新


Devilu
85 声望4 粉丝

just a newbie