• 链表


    一.链表由N个结点组成。结点的结构如下

    1.head.val表示结点head的值,用于比较,或者重设

    2.head.next表示结点head的next指针存储(连接)下一个结点的内存地址

    class ListNode {
        int val;
        ListNode next;
        ListNode(int x) {
            val = x;
            next = null;
        }
    }

    二.改变链表结构的操作(插入、删除),需要注意空结点,防止出现越界异常。

    1.在head结点后插入新结点,前提head结点不是空结点

    new_node.next = head.next;(新结点的next指针记录了head结点下个结点的内存地址。)

    head.next=new_node; (head结点的next指针记录了新结点的地址。)

    2.删除head后一个结点,前提要head的下一个结点不是空结点。

    head.next = head.next.next;(head.next.next表示head结点的next指针存储了head结点的下下一个结点的内存地址。)

    三.虚拟结点

    1.ListNode dummy = head;(表示将head结点的内存地址赋值给dummmy变量,引用的概念,head与dummy内存地址一样,作为虚拟结点,方便遍历结点,输出结果)

    测试

    class ListNode {
        int val;
        ListNode next;
        ListNode(int x) {
            val = x;
            next = null;
        }
    }
    
    public class Main {
    
        public static void main(String[] args) {
        // write your code here
            ListNode node1 = new ListNode(1);
            ListNode node2 = new ListNode(2);
            ListNode node3 = new ListNode(3);
            ListNode head = node1;
    
            node1.next = node2;
            node2.next = node3;
    
            for (ListNode node = head;node != null;node = node.next)
            {
                System.out.printf("%d",node.val);
                System.out.printf("->");
            }
            System.out.printf("
    
    ");
            node1 = node2;
    
            for (ListNode node = head;node != null;node = node.next)
            {
                System.out.printf("%d",node.val);
                System.out.printf("->");
            }
    
            System.out.printf("
    
    %d",node1.next.val);
    
        }
    }

    2.删除链表中倒数第n个结点

    //删除链表中倒数第n个结点
        static ListNode removeNthFromEnd(ListNode head, int n) {
            if (n < 0)
            {
                return null;
            }
    
            ListNode dummy = new ListNode(0);
            dummy.next = head;
            for (int i = 0; i < n; i++)
            {
                if (head == null)
                {
                    return null;
                }
                head = head.next;
            }
    
            ListNode preDelete = dummy;
            while (head != null)
            {
                head = head.next;
                preDelete = preDelete.next;
            }
    
            preDelete.next = preDelete.next.next;
            return dummy.next;
        }

    3.将小于x的值放在x结点的左边,大于x的值放在x结点的右边。

    public ListNode partition(ListNode head,int x)
        {
            if (head == null)
            {
                return null;
            }
    
            ListNode leftDummy = new ListNode(0);
            ListNode rightDummy = new ListNode(0);
            ListNode left = leftDummy;
            ListNode right = rightDummy;
            while (head != null)
            {
                if (head.val < x)
                {
                    left.next = head;
                    left = head;
                }
                else
                {
                    right.next = head;
                    right = head;
                }
                head = head.next;
            }
            right.next = null;
            left.next = rightDummy.next;
            return leftDummy.next;
        }

    4.去除链表中重复的数

    public static ListNode deleteDuplicates(ListNode head)
        {
            if (head == null || head.next == null)
            {
                return head;
            }
    
            ListNode dummy = new ListNode(0);
            dummy.next = head;
            //
            head = dummy;
    
            while (head.next != null && head.next.next != null)//要比较的2个数都存在
            {
                if (head.next.val == head.next.next.val)//相邻2数是否相等
                {
                    int val = head.next.val;
                    while (head.next != null && head.next.val == val)//是否存在连续相等的情况
                    {
                        //删除操作
                        head.next = head.next.next;
                    }
                }
                else
                {
                    //移动手指
                    head = head.next;
                }
            }
            return dummy.next;
        }

     5.重排链表,重排后的顺序(L1)->(Ln)->(L2)->(Ln-1)->(L3)->(Ln-2)

    public static void reorderList(ListNode head)
        {
            //
            if (head == null || head.next == null)
            {
                return;
            }
            ListNode mid = findMiddle(head);
            ListNode tail = reverse(mid.next);
            mid.next = null;//防止回环
            merge(mid,tail);
        }
    
        //找中间位置(经典)
        public static ListNode findMiddle(ListNode head)
        {
            ListNode fast = head.next;
            ListNode slow = head;
            while (fast != null && fast.next != null)
            {
                fast = fast.next.next;
                slow = slow.next;
            }
            return slow;
        }
    
        //1->2->3->null (null<-1<-2<-3)翻转链表(经典)
        public static ListNode reverse(ListNode head)
        {
            //
            ListNode newHead = null;
            while (head != null)
            {
                ListNode temp = head.next;
                head.next = newHead;
                newHead = head;
                head = temp;
            }
            return newHead;
        }
    
        //合并2链表(经典)
        public static void merge(ListNode head1,ListNode head2)
        {
            ListNode dummy = new ListNode(0);
            int index = 0;
            while (head1 != null && head2 != null)
            {
                if (index % 2 == 0)
                {
                    dummy.next = head1;
                    head1 = head1.next;
                }
                else
                {
                    dummy.next = head2;
                    head2 = head2.next;
                }
                index++;
                dummy = dummy.next;
            }
            //补刀,加入最后1个数
            if (head1 != null)
            {
                dummy.next = head1;
            }
            else
            {
                dummy.next = head2;
            }
        }
  • 相关阅读:
    【文字检测算法整理】
    【LDA】周志华
    【PCA】周志华
    【SVM】周志华
    4.1、顺序栈的实现(java实现)
    3.1、双向循环链表(java实现)
    5、链表队列(java实现)
    4、链栈的实现(java代码)
    3、循环链表(java实现)
    CommonsMultipartFile 转为 File 类型
  • 原文地址:https://www.cnblogs.com/huen/p/5212074.html
Copyright © 2020-2023  润新知