JAVA数据结构与算法-循环链表(5)

一、双向循环

public class CircleDoubleLinkedList
{

    DoubleNode headNode = null;

    void add(DoubleNode node) {
        // 当头结点为空
        if (headNode == null) {
            headNode = node;
            headNode.preNode = headNode;
            headNode.postNode = headNode;
        }
        DoubleNode tmp = headNode;
        //找到最后一个节点
        while (tmp.postNode != headNode) {
            tmp = tmp.postNode;
        }
        tmp.postNode = node;
        node.preNode = tmp;
        node.postNode = headNode;
        headNode.preNode = node;
    }

    void delete(int rank) {
        DoubleNode tmp = headNode;
        if (headNode == null) {
            System.out.println("空");
            return;
        }
        // 标记当删除节点是headNode的情况
        if (headNode.rank == rank) {
            if (headNode.postNode == headNode) {//只有一个头结点
                headNode = null;
            }
            else {//删除头结点 要注意更新链表的头结点
                headNode.preNode.postNode = headNode.postNode;
                headNode.postNode.preNode = headNode.preNode;
                headNode = headNode.postNode;
            }
            return;
        }
        tmp = tmp.postNode;
        //遍历查找要删除的节点
        while (tmp.rank != rank && tmp != headNode) {
            tmp = tmp.postNode;
        }
        //查到最后 没有该节点
        if (tmp == headNode) {
            System.out.println("没有此节点");
            return;
        }
        // 删除
        tmp.preNode.postNode = tmp.postNode;
        tmp.postNode.preNode = tmp.preNode;

    }

    void traverse() {
        DoubleNode tmp = headNode;
        if (tmp == null) {
            System.out.println("空");
            return;
        }
        System.out.println(tmp);
        while (tmp.postNode != headNode) {
            tmp = tmp.postNode;
            System.out.println(tmp);
        }
    }

}

二、单向循环+约瑟夫问题(也可用数组取模解决)

/*Josephu  问题为:设编号为1,2,… n的n个人围坐一圈,
    约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,
    它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,
    由此产生一个出队编号的序列。*/
public class CircleSingleLinkedList
{

    SingleNode first = null;

    void add(SingleNode node) {
        // 只有首节点为空,直接加入
        if (first == null) {
            first = node;
            node.next = node;
        }
        SingleNode tmp = first;
        // 遍历到最后插入
        while (tmp.next != first) {
            tmp = tmp.next;
        }
        tmp.next = node;
        node.next = first;
    }

    void traverse() {
        if (first == null) {
            System.out.println("空");
            return;
        }
        SingleNode tmp = first;
        System.out.println(tmp);
        while (tmp.next != first){
            tmp = tmp.next;
            System.out.println(tmp);
        }
    }

    void del(int rank) {
        // 删除节点是否是首结点的标志
        boolean flag = false;
        // 如果链表为空,返回空
        if (first == null){
            System.out.println("空");
            return;
        }

        // 判断头结点的rank是否等于要删除的节点
        if (first.rank == rank){
            if (first.next == first){//如果只有头结点,则直接返回头结点,头结点重置
                first = null;
                return;
            }else {//如果还有其他节点,将flag置为true,因为还要遍历到链表尾,才好删除头结点(适用于链表不重复的情况)
                flag = true;
            }
        }
        SingleNode tmp = first;
        // 遍历链表直到找到目标节点或指针指向链表尾
        while (tmp.next.rank != rank && tmp.next != first){
            tmp = tmp.next;
        }
        // 如果标记为true,操作头结点
        if (flag){
            tmp.next = first.next;
            first = first.next;
            return;
        }
        // 遍历到链表尾
        if (tmp.next == first){
            System.out.println("不存在该节点");
            return;
        }
        // 删除节点
        tmp.next = tmp.next.next;

    }

    public void josephu(int k, int m) {

        SingleNode tmp = first;
        // 找到第k个人
        while (tmp.rank != k){
            tmp = tmp.next;
        }
        int index = 1;
        // 遍历,直到只剩头结点
        while (first.next != first){
            if (index == m){//当计数器到m时
                //打印节点信息
                System.out.println(tmp);
                // 记录节点值
                int rank = tmp.rank;
                // 指针指向下一位
                tmp = tmp.next;
                // 删除之前记录的值对应的节点
                del(rank);
                //重置计数器
                index = 1;
                continue;
            }
            index++;
            tmp = tmp.next;
        }
        // 打印最后剩下的头节点
        System.out.println(first);
    }
}

你可能感兴趣的:(数据结构与算法,数据结构,算法,java)