5 个常见的链表操作

291 阅读2分钟

/**

    1. 单链表反转
    1. 链表中环的检测
    1. 两个有序的链表合并
    1. 删除链表倒数第n个结点
    1. 求链表的中间结点 */

public class LinkedList {

//1.单链表反转
public static Node reverse(Node list){
    Node current=list,pre=null;
    while(current!=null){
        Node next=current.next;
        current.next=pre;
        pre=current;
        current=next;
    }
    return pre;
}

//2.检测环
public static boolean checkCircle(Node list){
    if(list==null) return false;
    Node fast=list.next;
    Node slow=list;
    while(fast!=null&&fast.next!=null){
        fast=fast.next.next;
        slow=slow.next;
        if(fast==slow) return true;
    }
    return false;
}

//3.有序列表合并 Leetcode 21
//时间复杂度:O(n + m)O(n+m) ,其中 nn 和 mm 分别为两个链表的长度。因为每次循环迭代中,l1 和 l2 只有一个元素会被放进合并链表中, 因此 while 循环的次数不会超过两个链表的长度之和。所有其他操作的时间复杂度都是常数级别的,因此总的时间复杂度为 O(n+m)O(n+m)。
//
//空间复杂度:O(1)O(1) 。我们只需要常数的空间存放若干变量。
//
//作者:LeetCode-Solution
//链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode-solu/
//来源:力扣(LeetCode)

public ListNode mergeTwoLists(ListNode l1 ,ListNode l2){
    //哨兵节点soldier
    ListNode soldier = new ListNode(0);
    ListNode p = soldier;
    while ( l1 != null && l2 != null ){
        if ( l1.val < l2.val ){
            p.next = l1;
            l1 = l1.next;
        }
        else{
            p.next = l2;
            l2 = l2.next;
        }
        p = p.next;
    }
    // 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
    p.next = l1 == null ? l2 : l1;
    return soldier.next;
}
public static class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

//4.删除倒数第K个结点
public static Node deleteLastKth(Node list, int k) {
    Node fast = list;
    int i = 1;
    while (fast != null && i < k) {
        fast = fast.next;
        ++i;
    }

    if (fast == null) return list;
    Node slow = list;
    Node prev = null;
    while (fast.next != null) {
        fast = fast.next;
        prev = slow;
        slow = slow.next;
    }

    if (prev == null) {
        list = list.next;
    } else {
        prev.next = prev.next.next;
    }
    return list;
}

//5.求中间结点(非环链)
public static Node findMiddleNode(Node list) {
    if (list == null) return null;

    Node fast = list;
    Node slow = list;

    while (fast != null && fast.next != null) {
        fast = fast.next.next;
        slow = slow.next;
    }
    return slow;
}
public static Node createNode(int value){
    return new Node(value,null);
}

public static class Node{
    private int data;
    private Node next;

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

    public int getData(){
        return data;
    }
}

}