数据结构-链表

一. 链表(Linked List)介绍

链表是有序的列表,但存储方式不一定连续

  • 链表是以节点的方式来存储,是链式存储
  • 每个节点包含 data 域, next 域: 指向下一个节点

二. 代码实现

1.求单链表中有效节点的个数 (遍历链表)
2. 查找单链表中的倒数第 k 个结点

public class LinkList {

    //思路
    //1. 编写一个方法, 接收 head 节点, 同时接收一个 index
    //2. index 表示是倒数第 index 个节点
    //3. 先把链表从头到尾遍历, 得到链表的总的长度 getLength
    //4. 得到 size 后, 我们从链表的第一个开始遍历 (size-index)个, 就可以得到
    //5. 如果找到了, 则返回该节点, 否则返回 nulll
    public static Node findLastIndexNode(Node head, int index) {
        //判断如果链表为空, 返回 null
        if (head.next == null) {
            return null;
        }
        int size = getLength(head);
        Node cur = head.next;
        for (int i = 0; i < size - index; i++) {
            cur = head.next;
        }
        return cur;
    }

    public static int getLength(Node head) {
        if (head.next == null) {
            return 0;
        }
        int length = 0;
        Node cur = head.next;
        while (cur != null) {
            length++;
            cur = cur.next;
        }
        return length;
    }

    //    链表翻转 头插法
    public static void reverseList(Node head) {
        if (head.next == null || head.next.next == null) {
            return;
        }
        //定义一个辅助的指针(变量), 帮助我们遍历原来的链表
        Node cur = head.next;
        //当前节点下一节点
        Node next = null;
        Node reverseHead = new Node(0, null);
        while (cur != null) {
            //先暂时保存当前节点的下一个节点
            next = cur.next;
            //将 cur 的下一个节点指向新的链表的最前端
            cur.next = reverseHead.next;
            reverseHead.next = cur;
            cur = next;
        }
        head.next = reverseHead.next;
    }

    public static void main(String[] args) {
        Node node4 = new Node(4, null);
        Node node3 = new Node(3, node4);
        Node node2 = new Node(2, node3);
        Node node1 = new Node(1, node2);

        Node node = new Node(0, node1);
        System.out.println(node);
        reverseList(node);

        System.out.println(node);

    }

}

class Node {
    public Integer val;
    public Node next;

    public Node(Integer val, Node next) {
        this.val = val;
        this.next = next;
    }

    @Override
    public String toString() {
        return "Node{" +
                "val=" + val +
                ", next=" + next +
                '}';
    }
}

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

class CircleSingleLinkedList {
    // 创建一个 first 节点,当前没有编号
    private Node first = null;

    public void addNode(int nums) {
        if (nums < 1) {
            System.out.println("nums 的值不正确");
            return;
        }
        // 辅助指针, 帮助构建环形链表
        Node curBoy = null;
        for (int i = 1; i <= nums; i++) {
            // 根据编号, 创建小孩节点
            Node boy = new Node(i, null);
            // 如果是第一个小孩
            if (i == 1) {
                first = boy;
                first.next = first; // 构成环
                curBoy = first; // 让 curBoy 指向第一个小孩
            } else {
                curBoy.next = boy;//
                boy.next = first;//
                curBoy = boy;
            }
        }
    }

    public void showNode() {
        if (first == null) {
            System.out.println("没有节点");
            return;
        }
        Node cur = first;
        while (true) {
            System.out.printf("编号 %d\n", cur.val);
            if (cur.next == first) {
                break;
            }
            cur = cur.next;
        }
    }

    /**
     * @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;
        }
        Node help = first;
        while (true) {
            if (help.next == first) {
                break;
            }
            help = first.next;
        }
        for (int i = 0; i <startNo-1 ; i++) {
            first = first.next;
            help = help.next;
        }
        while (true){
            if(help == first){
                break;
            }
            for (int i = 0; i <countNum-1 ; i++) {
                first = first.next;
                help = help.next;
            }
            System.out.printf("节点 %d 出圈\n", first.val);
            first = first.next;
            help.next = first;
        }
    }
}
posted @ 2021-05-08 16:04  小阿Q的博客  阅读(54)  评论(0编辑  收藏  举报