zoukankan      html  css  js  c++  java
  • 数据结构-链表

    一. 链表(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
    ", 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 出圈
    ", first.val);
                first = first.next;
                help.next = first;
            }
        }
    }
    
  • 相关阅读:
    UVA 10618 Tango Tango Insurrection
    UVA 10118 Free Candies
    HDU 1024 Max Sum Plus Plus
    POJ 1984 Navigation Nightmare
    CODEVS 3546 矩阵链乘法
    UVA 1625 Color Length
    UVA 1347 Tour
    UVA 437 The Tower of Babylon
    UVA 1622 Robot
    UVA127-"Accordian" Patience(模拟)
  • 原文地址:https://www.cnblogs.com/gcm688/p/14663896.html
Copyright © 2011-2022 走看看