Data structure_5: linked list and recursion

Linked lists and recursion

The answer to the problem of deleting linked list elements

Problem description: Delete the element with value 6 in the linked list [1, 2, 6, 3, 4, 5, 6]

  • ListNode.java Structure description

    public class ListNode {
          
          
        int val;
        ListNode next;
    
        ListNode(int x) {
          
          val = x;}
    
        /**
        * 链表节点构造函数,自定义
        * @param arr
        */
        ListNode(int[] arr) {
          
          
            if (arr == null || arr.length == 0) {
          
          
                throw new IllegalArgumentException("arr can not be empty");
            }
            this.val = arr[0];
            ListNode cur = this;
            for (int i = 1; i < arr.length; i++) {
          
          
                cur.next = new ListNode(arr[i]);
                cur = cur.next;
            }
        }
    
        @Override
        public String toString() {
          
          
            StringBuilder sb = new StringBuilder();
            ListNode cur = this;
            while (cur != null) {
          
          
                sb.append(cur.val).append(" -> ");
                cur = cur.next;
            }
            sb.append("NULL");
            return sb.toString();
        }
    }
    
  • In the conventional way, the three parts [head, middle, and tail] of the linked list are processed separately

    public ListNode removeElement(ListNode head, int val) {
          
          
            // 链表头部节点删除
            while (head != null && head.val == val)
                head = head.next;
    
            // 链表尾部节点删除
            if (head == null) {
          
          
                return null;
            }
    
            // 链表中间部分节点删除
            ListNode prev = head;
            while (prev.next != null) {
          
          
                if (prev.next.val == val)
                    prev.next = prev.next.next;
                else
                    prev = prev.next;
            }
    
            return head;
        }
    }
    
  • The virtual head node method makes each linked list node contain a pre-node, improving the code

     public ListNode removeElement(ListNode head, int val) {
          
          
        // 建立虚拟头结点,保证链表中每一个节点前面均有节点
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
    
        // 链表节点删除
        ListNode prev = dummyHead;
        while (prev.next != null) {
          
          
            if (prev.next.val == val)
                prev.next = prev.next.next;
            else
                prev = prev.next;
        }
    
        return dummyHead.next;
    }
    
  • have a test!

    public static void main(String[] args) {
          
          
        int[] arr = {
          
          1, 2, 6, 3, 4, 5, 6};
        ListNode res = new ListNode(arr);
        System.out.println(res);
        new Solution2().removeElement(res, 6);
        System.out.println(res);
    }
    ------------------------------------------
    1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6 -> NULL
    1 -> 2 -> 3 -> 4 -> 5 -> NULL
    

Recursion: a very important component logic mechanism in computers

  • Essentially, the original problem is transformed into a smaller same problem, such as the sum of arrays!

    SUM(arr[0...n-1]) = arr[0] + SUM(arr[1...n-1])

    SUM(arr[1...n-1]) = arr[1] + SUM(arr[2...n-1])

    SUM(arr[n-1...n-1]) = arr[n-1] + SUM(arr[]) = arr[n-1] + 0

  • The composition of the recursive algorithm

    • 求解最基本的问题
    • 把原问题转化成更小的问题
  • Linked lists are recursive

    • Linked list can be understood as a connection body of multiple nodes, and can also be regarded as 一个节点和一个链表a connection body.
    • It is NULLalso the most basic linked list.
    • In order to facilitate understanding, I drew a picture!
      Insert picture description here
    • According to the picture, we can rewrite the code!
    public ListNode removeElementNew(ListNode head, int val) {
          
          
        // 基础问题 one
        if (head == null) {
          
          
            return null;
        }
        // 处理子链表,分解问题 two
        head.next = removeElementNew(head.next, val);
        // 处理结果,若当前返回子链表满足条件,便跳过节点 three
        return head.val == val ? head.next : head;
    }
    
    • For example, now there is a linked list 1, 2, 3, and I want to delete an element. 2How is the above method performed?
      • step1Enter [1, 2, 3] a linked list with 1 as the head node
        • one head != null
        • two head.next =?, enter the first recursion,step2
      • step2Enter [2, 3] a linked list with 2 as the head node
        • one head != null
        • two head.next =?, enter the second recursion,step3
      • step3Entry [3] Linked list with 3 as the head node
        • one head != null
        • two head.next =?, enter the third recursion,step4
      • step4Input parameter [NULL], NULL linked list
        • one head == null , return null, the basic problem has appeared! ! !
      • step5 Back tostep3 two
        • two head.next = 【null】
        • three head.val == 2? head.next : head
        • return head , now the linked list is [3], returnstep2 two
      • step6 Back tostep2 two
        • two head.next = 【3】
        • three head.val == 2? head.next : head, 此时条件满足,为true
        • return head.next , now the linked list is [3], returnstep1 two
      • step7 Back tostep1 two
        • two head.next = 【3】
        • three head.val == 2? head.next : head
        • head return , this time the list is [1, 3], back step1, has been carried over one, , two, threethe method returns, ends.
  • Recursive calls come at a cost: function call + system stack space (recording the current execution position, variable status, and time consumption). If the basic problem is not dealt with, that is, there is no recursive exit, the method execution will occupy memory until the memory is full or overflow , Causing the system to over. An algorithm must always end after a limited number of executions, and each step can be completed in a limited time.

Guess you like

Origin blog.csdn.net/Nerver_77/article/details/102997165