• 2.链表


    链表(单链表)是一种通过指针将一组零散的内存块串联起来的数据结构,每个链表的结点除了存储的数据之外,还需要记录链上的下一个节点的地址

    • 链表的插入和删除(给定节点指针)时间复杂度O(1),但遍历删除的时间复杂度是O(n)

    • 双向链表:每个结点不止有一个后继指针指向后面的结点,还有一个前驱指针指向前面的结点。在删除指定指针指向的节点时,时间复杂度仅为O(1)若链表是有序链表,那么查找时可以向前向后遍历,平均能少遍历一半的数据

    • 链表有关算法

      • 单链表反转
        定义两个节点curr,pre。curr.next指向pre,然后curr、pre后移一位,重复直到最后一个节点。​

      • 检测环
        1.快慢指针,快指针每次走两步,慢指针每次走一步。​相遇则说明有环
        2.遍历链表并将节点值加入散列表中,若有重复的说明有环​

      • 有序链表合并
        定义一个哨兵,每次加入较小节点,最后加入较长链表剩余部分

      • 删除倒数第k个节点
        定义快慢指针,从头节点开始快指针先走k-1步,然后快慢同时走,快指针走到表尾时慢指针指向的就是倒数第k个

      • 求中间节点
        快慢指针,快指针每次两步慢指针每次一步,快指针走到表尾慢指针指向中间节点

      • 判断回文
        快慢指针找到中点,慢指针移动过程中同时反转链表,然后从中点至两端一起移动并判断

    链表Java实现

    
    public class myLinkedlist {
        public Node head;
    
        public myLinkedlist() {
            head = new Node(-1);
        }
    
        /**
         * 将data加到链表尾部
         *
         * @param data
         * @return
         */
        public boolean append(int data) {
            Node iter = head;
            while (iter.next != null) iter = iter.next;
            iter.next = new Node(data);
            return true;
        }
    
        /**
         * 将value插入到index之后
         *
         * @param index
         * @return
         */
        public boolean insertAfter(int index, int value) {
            Node iter = head;
            while (iter.data != index && iter.next != null) iter = iter.next;
            if (iter.data != index && iter.next == null) {
                System.out.println("链表中无对应节点!");
                return false;
            }
    
            Node temp = iter.next;
            iter.next = new Node(value);
            iter.next.next = temp;
    
            return true;
        }
    
        public boolean delete(int index) {
            Node iter = head;
            while (iter.next != null && iter.next.data != index) iter = iter.next;
            if (iter.data != index && iter.next == null) {
                System.out.println("链表中无对应节点!");
                return false;
            }
            Node temp = iter.next.next;
            iter.next = temp;
            return true;
        }
    
        /**
         * 反转链表
         */
        public void reverse() {
            Node iter = head.next;
    
            if (iter.next == null)
                return;
    
            Node pre = iter;
            Node mid = iter.next;
            Node after = mid.next;
            pre.next = null;
    
            //after为null时说明mid是最后一个
            while (after != null) {
                //每次将mid指向pre
                mid.next = pre;
                pre = mid;
                mid = after;
                after = after.next;
            }
            mid.next = pre;
            head.next = mid;
        }
    
        public boolean isPalindrome() {
            if (head.next == null) {
                System.out.println("链表为空!");
                return false;
            }
            //只有两个节点
            if (head.next.next.next == null) {
                int first = head.next.data;
                int second = head.next.next.data;
                if (first == second)
                    return true;
                else
                    return false;
            }
            Node fast;//快指针
            Node slow;//慢指针
            fast = slow = head.next;
            int fStep;//快指针步数
            int sStep;//慢指针步数
            fStep = sStep = 0;
            while (fast.next != null) {
                fast = fast.next;
                fStep++;
            }
            sStep = fStep / 2;
    
            //慢指针向前移动,同时将单链表反转
            Node pre, mid, after;
            pre = slow;
            mid = slow.next;
            after = mid.next;
    
            slow.next = null;
    
            while (sStep > 0) {
                mid.next = pre;
                pre = mid;
                mid = after;
                after = after.next;
                sStep--;
            }
    
            Node toStart, toEnd;
            //奇数遍历起点
            if (fStep % 2 == 1) {
                toStart = pre;
                toEnd = mid;
            }
            //偶数遍历起点
            else {
                toStart = pre.next;
                toEnd = mid;
            }
    
            do {
                if (toStart.data != toEnd.data)
                    return false;
                toStart = toStart.next;
                toEnd = toEnd.next;
            } while (toStart != null && toEnd != null);
            return true;
        }
    
        public String toString() {
            StringBuilder builder = new StringBuilder();
            Node iter = head;
            int size = 0;
            while (iter.next != null) {
                builder.append(iter.next.data + ",");
                size ++;
                iter = iter.next;
            }
            return builder.toString() + "	(size: " + size + ")";
        }
    
        public void linkedlistTest(){
            myLinkedlist test = new myLinkedlist();
            test.append(1);
            System.out.println(test.toString());
            test.delete(1);
            System.out.println(test.toString());
            test.append(2);
            System.out.println(test.toString());
            test.insertAfter(1,3);
            System.out.println(test.toString());
            test.delete(2);
            System.out.println(test.toString());
            test.append(4);
            test.append(5);
            test.append(6);
            System.out.println(test.toString());
            test.reverse();
            System.out.println(test.toString());
            test.reverse();
            System.out.println(test.toString());
            //测试是否为回文串
            test.append(1);
            test.append(2);
            test.append(3);
            test.append(2);
            test.append(1);
            System.out.println(test.isPalindrome());
        }
    
    
    }
    
    class Node {
        int data;
        Node next;
    
        protected Node(int data) {
            this.data = data;
            this.next = null;
        }
    }
    
  • 相关阅读:
    Character Encoding题解(容斥)
    P1445 [Violet]樱花 题解(推式子)
    F. Stone 题解(对称博弈)
    M. 810975 题解(容斥)
    P1365 WJMZBMR打osu! / Easy 题解(期望dp)
    icpc济南
    C#创建windows服务并定时执行
    批处理 windows 服务的安装与卸载
    前台单击文件,jQuery删除后台相应真实的文件
    Jquery直接调用后台方法(WebMethod框架的使用)
  • 原文地址:https://www.cnblogs.com/codespoon/p/13231096.html
Copyright © 2020-2023  润新知