【数据结构】链表的实现

继上篇:

  • 删除 val的值、有序合并两个链表(从小到大)
class Node {
    int val;
    Node next = null;

    public Node(int val) {
        this.val = val;
    }
}

public class Solution {
    //删除 val的值
    Node removeAll(Node head, int val) {
        Node prev = null;
        Node cur = head;
        while (cur != null) {
            if (cur.val == val) {
                if (cur == head) {
                    head = cur.next;
                } else {
                    prev.next = cur.next;
                }
            } else {
                prev = cur;
            }
            cur = cur.next;
        }
        return head;
    }
//有序合并两个链表(从小到大)
    Node merge(Node head1, Node head2) {
        if (head1 == null) {
            return head2;
        }

        if (head2 == null) {
            return head1;
        }

        Node result = null;
        Node last = null;

        Node cur1 = head1;
        Node cur2 = head2;

        while (cur1 != null && cur2 != null) {
            if (cur1.val <= cur2.val) {
                if (result == null) {
                    result = cur1;
                } else {
                    last.next = cur1;
                }
                last = cur1;
                cur1 = cur1.next;
            } else {
                if (result == null) {
                    result = cur2;
                } else {
                    last.next = cur2;
                }
                last = cur2;
                cur2 = cur2.next;
            }
        }

        if (cur1 != null) {
            last.next = cur1;
        } else {
            last.next = cur2;
        }

        return result;
    }

    public static Node createList() {
        Node n1 = new Node(6);
        Node n3 = new Node(2);
        Node n4 = new Node(6);
        Node n6 = new Node(4);
        Node n8 = new Node(6);

        n1.next = n3;
        n3.next = n4;
        n4.next = n6;
        n6.next = n8;

        return n1;
    }

    public static Node createList1() {
        Node n1 = new Node(1);
        Node n2 = new Node(2);

        n1.next = n2;

        return n1;
    }

    public static Node createList2() {
        Node n1 = new Node(1);
        Node n2 = new Node(3);
        Node n3 = new Node(5);
        Node n4 = new Node(7);

        n1.next = n2;
        n2.next = n3;
        n3.next = n4;

        return n1;
    }

    public static void main(String[] args) {
        Node head = createList();

        Node result = new Solution().removeAll(head, 6);
        for (Node cur = result; cur != null; cur = cur.next) {
            System.out.println(cur.val);
        }

        System.out.println("=====================");

        Node head1 = createList1();
        Node head2 = createList2();
        Node merged = new Solution().merge(head1, head2);
        for (Node cur = merged; cur != null; cur = cur.next) {
            System.out.println(cur.val);
        }
    }
}
  • 给定一个 val 值,链表中小于 val 的值放在左边,大于 val 的值放在右边,返回头结点 head
class ListNode {
    public int val;
    public ListNode next;

    public ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }

    public ListNode(int val) {
        this(val, null);
    }
}

public class LinkedListInterview {
    //给定一个 val 值,链表中小于 val 的值放在左边,大于 val 的值放在右边,返回头结点 head
    
    
    
    public ListNode separateByX(ListNode head, int x) {
         /*
        遍历整个链表,把小于 x 的尾插到一个小链表
                      把大于等于 x 的尾插到一个大链表中
        理想情况下,把大链表接到小链表后边
        1) 如果没有小链表,直接返回大链表(大链表可能为空)

        保证,返回链表的最后一个结点.next == null
        sEnd / bEnd
         */
        /* 尾插
        1. 先情况讨论:
            1)如果当前链表为空,要插入的结点就是链表的第一个结点
            2) 如果链表不为空,
                1. 先找到当前的最后一个结点
                2. 让当前的最后一个结点的 next = 要插入的结点
                3. 如果每次的最后一个结点都是我们插入的
                    可以记录上次插入的最后一个结点
                4. 不要忘记更新最后一个结点
         */

        
        ListNode sHead = null;// 指向小链表的第一个结点
        ListNode sEnd = null;// 记录小链表的最后一个结点
        ListNode bHead = null;
        ListNode bEnd = null;

        for (ListNode cur = head; cur != null; cur = cur.next) {
            if (cur.val < x) {
                 /* 尾插到小的链表中 */
                if (sHead == null) {
                    sHead = cur;
                } else {
                    sEnd.next = cur;
                }
                sEnd = cur;
            } else {
                /* 尾插到大的链表中 */
                // 同理
                if (bHead == null) {
                    bHead = cur;
                } else {
                    bEnd.next = cur;
                }
                bEnd = cur;
            }
        }

        if (sEnd == null) {
            return bHead;
        }

        sEnd.next = bHead;
        if (bEnd != null) {
            bEnd.next = null;
        }
        return sHead;
    }





    private static ListNode createTestList() {
        ListNode n1 = new ListNode(4);
        ListNode n2 = new ListNode(5);
        ListNode n3 = new ListNode(2);
        ListNode n4 = new ListNode(7);
        ListNode n5 = new ListNode(6);
        ListNode n6 = new ListNode(3);
        ListNode n7 = new ListNode(8);
        ListNode n8 = new ListNode(1);

        n1.next = n2;
        n2.next = n3;
        n3.next = n4;
        n4.next = n5;
        n5.next = n6;
        n6.next = n7;
        n7.next = n8;

        return n1;
    }
    
    private static void test() {
        // 4 5 2 7 6 3 8 1
        ListNode head = createTestList();
        ListNode result = new LinkedListInterview().separateByX(head, 5);
        // 4 2 3 1 5 7 6 8
        for (ListNode cur = result; cur != null; cur = cur.next) {
            System.out.println(cur.val);
        }
    }

    public static void main(String[] args) {
        test();
    }
}
  • 复杂链表的深度复制
public class Solution {
    CNode copy(CNode head) {
        if (head == null) {
            return null;
        }

        CNode p1 = head;
        while (p1 != null) {
            CNode p2 = new CNode(p1.val);

            p2.next = p1.next;
            p1.next = p2;

            p1 = p2.next;
        }

        p1 = head;
        while (p1 != null) {
            CNode p2 = p1.next;
            if (p1.random != null) {
                p2.random = p1.random.next;
            }

            p1 = p2.next;
        }

        p1 = head;
        CNode newHead = head.next;
        while (p1 != null) {
            CNode p2 = p1.next;
            p1.next = p2.next;
            if (p2.next != null) {
                p2.next = p2.next.next;
            }

            p1 = p1.next;
        }

        return newHead;
    }
}




//psvm
public static void main(String[] args) {
    Solution solution = new Solution();
    testComplexListCopy(solution);
    //testReverseList();
    //testRemoveAll();
}
private static void testComplexListCopy(Solution solution) {
    // 1. 构建测试数据
    CNode head = createComplexList1();
    // 2. 进行测试
    CNode resultHead = solution.copy(head);
    // 3. 对测试结果进行打印
    printCList(resultHead);
}

// CNode 必须有一个构造方法,形参是 int val
// 并且,初始化后,next 和 random 都是 null
private static CNode createComplexList1() {
    CNode n1 = new CNode(1);
    CNode n2 = new CNode(2);
    CNode n3 = new CNode(3);
    CNode n4 = new CNode(4);

    n1.random = n3; n2.random = n1; n3.random = n3;
    n1.next = n2; n2.next = n3; n3.next = n4;

    return n1;
}

// CNode 必须实现一个 String toString() 方法
//打印
private static void printCList(CNode head) {
    for (CNode cur = head; cur != null; cur = cur.next) {
        System.out.print(cur + " --> ");
    }
    System.out.println();
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值