单向链表与循环链表

1.背景

 

 

2.代码

package com.ldp.structure.demo01;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 姿势帝-博客园
 * @address https://www.cnblogs.com/newAndHui/
 * @WeChat 851298348
 * @create 04/09 7:01
 * @description <P>
 * 约瑟夫问题
 * </P>
 */
public class Test03 {
    // 总人数
    int size = 10;
    // 从第k个人开始
    int k = 5;
    // 每次数m个
    int m = 8000;

    /**
     * 测试约瑟夫,丢手帕问题
     */
    @Test
    public void test01() {
        List<Node> delList = new ArrayList<>();
        Node head = createNode(size);
        print(head);
        int i = 1;
        long l = System.currentTimeMillis();
        while (true) {
            // 采用取模的方式当m较大时可以大大提高效率
            if (i % size == (k + m - 1) % size) {
                // if (i == (k + m - 1)) {
                // 删除下一个节点
                Node current = head;//A
                Node deleteNode = head.next; // B
                Node next2 = head.next.next; // A
                if (current == next2) {
                    // 最后两个元素
                    // System.out.println("删除节点:" + deleteNode.data);
                    delList.add(deleteNode);
                    head.next = null;
                    print(head);
                    // System.out.println("删除[最后一个]节点:" + current.data);
                    delList.add(current);
                    break;
                }
                current.next = next2;
                head = next2;
                // System.out.println("删除节点:" + deleteNode.data);
                delList.add(deleteNode);
                print(head);
                k = 1;
                i = 1;
                size--;
            } else {
                head = head.next;
            }
            i++;
        }
        System.out.println("耗时:" + (System.currentTimeMillis() - l));
        // 遍历出队列
        System.out.println("出来的顺序...");
        for (Node node : delList) {
            System.out.println(node.data);
        }
    }

    /**
     * 测试链表反正
     * 重点是
     * 1.遍历链表
     * 2.在头部加入节点
     */
    @Test
    public void test02() {
        SingleLinkedList linkedList = new SingleLinkedList();
        Node nodeA = new Node("A", null);
        Node nodeB = new Node("B", null);
        Node nodeC = new Node("C", null);
        Node nodeD = new Node("D", null);
        linkedList.addLast(nodeA);
        linkedList.addLast(nodeB);
        linkedList.addLast(nodeC);
        linkedList.addLast(nodeD);
        linkedList.show();
        System.out.println("链表反转...");
        linkedList.res2(linkedList);
        linkedList.show();

    }

    /**
     * 循环创建节点
     *
     * @param size
     * @return 返回head节点
     */
    public Node createNode(int size) {
        Node head = null;
        Node currentNode = null;
        for (int i = 1; i <= size; i++) {
            if (i == 1) {
                // 第一个节点
                Node node = new Node("小朋友" + i, null);
                currentNode = node;
                head = node;
            } else if (i == size) {
                // 最后一个节点
                Node node = new Node("小朋友" + i, currentNode);
                head.next = node;
            } else {
                Node node = new Node("小朋友" + i, currentNode);
                currentNode = node;
            }
        }
        return head;
    }

    public void print(Node head) {
        System.out.print("留下的成员:");
        Node temp = head;
        while (true) {
            System.out.print(head.data + "\t\t");
            head = head.next;
            if (head == null || head == temp) {
                break;
            }
        }
        System.out.println();
    }
}

class SingleLinkedList {
    // 头结点
    Node head = new Node(null, null);

    /**
     * 添加到最后
     *
     * @param node
     */
    public void addLast(Node node) {
        Node temp = head;
        // 寻找最后一个节点
        while (true) {
            if (temp.next == null) {
                // temp就是最后一个节点
                break;
            } else {
                // 向下查看后面一个节点
                temp = temp.next;
            }
        }
        // 节点加到最后
        temp.next = node;
    }

    /**
     * 添加到头部
     *
     * @param node
     */
    public void addFirst(Node node) {
        // 取下当前所有有效节点
        Node temp = head.next;

        // 头结点--> 新节点
        head.next = node;
        // 新节点-->原来的节点
        node.next = temp;
    }

    /**
     * 遍历节点
     */
    public void show() {
        System.out.println("链表显示");
        Node temp = head;
        while (true) {
            if (temp.next == null) {
                break;
            }
            temp = temp.next;
            System.out.print(temp.data + " \t");
        }
        System.out.println();
    }

    /**
     * 链表反转
     *
     * @param linkedList
     */
    public void res(SingleLinkedList linkedList) {
        SingleLinkedList newLinkedList = new SingleLinkedList();
        Node current = linkedList.head.next;
        if (current == null || current.next == null) {
            return;
        }
        Node temp;
        while (true) {
            temp = current.next;
            newLinkedList.addFirst(current);
            if (temp == null) {
                break;
            } else {
                current = temp;
            }
        }
        // 将新链表 赋值 给 原来的链表
        linkedList.head.next = newLinkedList.head.next;
    }

    public void res2(SingleLinkedList linkedList) {
        Node newHead = new Node(null, null);
        Node current = linkedList.head.next;
        if (current == null || current.next == null) {
            return;
        }
        Node temp;
        while (true) {
            temp = current.next;
            // 加到新的头结点
            current.next = newHead.next;// 当前节点-->新链表的有效节点
            newHead.next = current;// 新的头结点-->当前节点
            // 当前节点指针下移
            if (temp == null) {
                break;
            } else {
                current = temp;
            }
        }
        // 将新链表 赋值 给 原来的链表
        linkedList.head.next = newHead.next;
    }
}

class Node {
    public Object data;
    public Node next;

    public Node(Object data, Node next) {
        this.data = data;
        this.next = next;
    }
}

 

完美!

posted @ 2022-04-10 10:37  不停学  阅读(38)  评论(0)    收藏  举报