把给定的值都删除

package class03;

import java.util.ArrayList;

/**
 * 把给定的值都删除
 * 入参:单链表的头节点head,要删除的数字num。
 * 返回值:把值是num的所有节点都删除后的单链表的头节点。
 * attention:删除的可能是头节点。删除的可能是连续的节点。
 */
public class Code02_RemoveNodes {
    static class Node {
        private int value;
        private Node next;

        public Node(int v) {
            value = v;
        }
    }

    //把给定的值都删除
    public static Node removeNodes(Node head, int num) {
        while (head != null) {
            if (head.value != num) {
                break;
            }
            head = head.next;
            //如果head.value == num,head就往下出溜。
            //如果从第一个节点开始,head.value一直等于num,那head就一直往下出溜。知道第一个不是num的节点出现。break;
        }
        //来到这儿
        //1) head == null
        //2) head != null
        //❤:) ^_^😀
        Node cur = head;//定义cur作为当前节点。
        Node pre = head;//定义pre作为当前节点cur的前一个节点。
        while (cur != null) {
            if (cur.value == num) {//当前节点的值等于num。
                pre.next = cur.next;//很关键。在cur每次要跳步之前,总是将pre的next,指向cur的next。
            } else {//如果当前节点的值,不等于num。
                pre = cur;//pre跳到cur的位置。可能是一下跳一步,也可能是一下跳很多步。
            }
            cur = cur.next;//不管当前节点的值,等不等于num,当前节点cur,都要跳一步。
        }
        //返回头节点。head可能是原来的旧头,也可能是跳过了很多个节点后的新头。
        return head;
    }

    public static void main(String[] args) {
        int maxSize = 6;
        int maxValue = 20;
        int testTimes = 10000;
        boolean flag = true;
        System.out.println("测试开始!");
        for (int i = 0; i < testTimes; i++) {
            Node node = generateRandomLinkedList(maxSize, maxValue);
//            Node node2 = copyLinkedList(node);
            Node node2 = copyRandomList(node);//have a look
            printLinkedList(node);
            int num = (int) (Math.random() * maxValue);//生成随机要删除的数字num
//            System.out.println("num = " + num);
            Node resultHeadNode = removeNodes(node, num);
            String s1 = printLinkedList(resultHeadNode);
            Node testHeadNode = test(node2, num);
            String s2 = printLinkedList(testHeadNode);
            boolean linkedListEquals = isLinkedListEquals(resultHeadNode, testHeadNode);
            if (!linkedListEquals) {
                flag = false;
                break;
            }
//            System.out.println("s1 = " + s1);
//            System.out.println("s2 = " + s2);
            if (!s1.equals(s2)) {
                flag = false;
                break;
            }
        }
        System.out.println("测试结束!");
        System.out.println(flag ? "nice!" : "oops!");
    }

    //打印单链表
    public static String printLinkedList(Node head) {
        StringBuilder s = new StringBuilder();
        while (head != null) {
//            System.out.print(head.value + "->");//打印
//            s.append(head.value).append("->");
            head = head.next;
        }
//        System.out.println("null");//打印
//        s.append("null");
//        System.out.println("s = " + s);//打印
        return s.toString();
    }

    //for test
    public static Node test(Node head, int num) {
        ArrayList<Node> list = new ArrayList<>();
        while (head != null) {
            if (head.value != num) {
                break;
            }
            head = head.next;
        }
        while (head != null) {
            list.add(head);
            head = head.next;
        }
        list.add(null);
        Node node0 = list.get(0);
        Node pre = node0;
        for (int i = 1; i < list.size() - 1; i++) {//node111
            if (list.get(i).value == num) {
                pre.next = list.get(i).next;
            } else {
                list.get(i).next = list.get(i + 1);
                pre = list.get(i);
            }
//            printLinkedList(list.get(0));
        }
        return node0;
    }

    //生成随机单链表
    public static Node generateRandomLinkedList(int maxSize, int maxValue) {
        int[] arr = new int[(int) (Math.random() * maxSize + 2)];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random() * maxValue);
        }
//        System.out.println("arr = " + Arrays.toString(arr));
        for (int i = 0; i < arr.length - 1; i++) {
            Node node0 = new Node(arr[i]);
            node0.next = new Node(arr[i + 1]);
        }
        Node node0 = new Node(arr[0]);
        Node pre = node0;
        for (int i = 1; i < arr.length; i++) {
            Node cur = new Node(arr[i]);
            pre.next = cur;
            pre = cur;
        }
        return node0;
    }

    //看两个链表是否相等
    public static boolean isLinkedListEquals(Node node1, Node node2) {
        if (node1 == null && node2 == null) {
            return true;
        }
        if (node1 == null && node2 != null) {
            return false;
        }
        if (node1 != null && node2 == null) {
            return false;
        }
        try {
            while (node1 != null || node2 != null) {
                if (node1.value != node2.value) {
                    return false;
                }
                node1 = node1.next;
                node2 = node2.next;
            }
        } catch (NullPointerException e) {
//            throw new RuntimeException(e);
            System.out.println("e = " + e);
            return false;
        }
        return true;
    }

    //1->1->2->3->null
    /*public static Node copyLinkedList(Node h1) {
        Node h2 = new Node(h1.value);
        Node cur = null;
        Node pre = h2;
        while (h1 != null) {
            cur = new Node(h1.value);
            pre.next = cur;
            pre = cur;
            h1 = h1.next;
            printLinkedList(h2);
        }
        return h2;
    }*/

    //复制链表
    public static Node copyRandomList(Node head) {///
        Node cur = head;
        Node dum = new Node(0);
        Node pre = dum;
        while (cur != null) {
            Node node = new Node(cur.value); // 复制节点 cur
            pre.next = node;               // 新链表的 前驱节点 -> 当前节点
            // pre.random = "???";         // 新链表的 「 前驱节点 -> 当前节点 」 无法确定
            cur = cur.next;                // 遍历下一节点
            pre = node;                    // 保存当前新节点
        }
        return dum.next;
    }

}

 

posted @ 2022-11-02 23:56  TheFloorIsNotTooHot  阅读(25)  评论(0)    收藏  举报