【玩转数据结构】----链表和递归

前言

链表和递归


一、删除链表中的元素


package com.zcw.data.recursion;

/**
 * @ClassName : ListNode
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-07-28 11:14
 */
public class ListNode {
    public int val;
    public ListNode next;


    public ListNode(int x){
        val =x;
    }
}

package com.zcw.data.recursion;

/**
 * @ClassName : Solution
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-07-28 11:13
 */
public class Solution {
    public ListNode removeElements(ListNode head,int val){
        while (head !=null && head.val == val){
            ListNode delNode = head;
            head = head.next;
            delNode.next = null;
        }
       if(head == null){
           return  null;
       }


       ListNode prev = head;
       while(prev.next !=null){
           if(prev.next.val == val){
               ListNode delNode = prev.next;
               prev.next = delNode.next;
               delNode.next = null;
           }else{
               prev = prev.next;
           }
       }
       return head;
    }
}


package com.zcw.data.recursion;

/**
 * @ClassName : Solution2
 * @Description :虚拟节点
 * @Author : Zhaocunwei
 * @Date: 2020-07-28 12:07
 */
public class Solution2 {
    public ListNode removeElements(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;
    }
}


二、测试上面代码

package com.zcw.data.recursion;

/**
 * @ClassName : ListNode
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-07-28 11:14
 */
public class ListNode {
    public int val;
    public ListNode next;


    public ListNode(int x){
        val =x;
    }

    /**
     * 链表节点的构造函数
     * 使用Arr为参数,创建一个链表,当前的ListNode链表头结点
     * @param arr
     */
    public 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 res = new StringBuilder();
        ListNode cur = this;
        while(cur !=null){
            res.append(cur.val + "->");
            cur = cur.next;
        }
        res.append("NULL");
        return res.toString();
    }
}


【玩转数据结构】----链表和递归_第1张图片

三、递归基础与递归的宏观语意

【玩转数据结构】----链表和递归_第2张图片

1.创建递归函数

package com.zcw.data.recursion;

/**
 * @ClassName : Sum
 * @Description :递归
 * @Author : Zhaocunwei
 * @Date: 2020-07-28 13:47
 */
public class Sum {
    public static int sum(int[] arr){
        return sum(arr,0);
    }

    /**
     * 递归函数
     * 计算arr[l...n]这个区间内所有数字的和
     * @return
     */
    private static int sum(int[] arr,int l){
        if(l == arr.length){
            return 0;
        }
        //这就是递归运算的调用
        return arr[l] + sum(arr,l+1);
    }

    public static void main(String[] args) {
        int[] nums = {1,2,3,4,5,6,7,8,};
        System.out.println(sum(nums));
    }
}


【玩转数据结构】----链表和递归_第3张图片

2.分析递归函数

【玩转数据结构】----链表和递归_第4张图片

四、链表的天然递归结构性质

【玩转数据结构】----链表和递归_第5张图片
【玩转数据结构】----链表和递归_第6张图片

package com.zcw.data.recursion;

/**
 * @ClassName : Solution3
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-07-28 14:02
 */
public class Solution3 {
    public ListNode removeElements(ListNode head ,int val){
        if(head == null){
            return null;
        }
        //第一种写法
//        ListNode res = removeElements(head.next,val);
//        if(head.val == val){
//            return res;
//        }else{
//            head.next = res;
//            return head;
//        }
        //第二种写法
        head.next = removeElements(head.next,val);
        return head.val == val ? head.next:head;
    }

    public static void main(String[] args) {
        int[] nums = {1,2,6,3,4,5,6};
        ListNode head = new ListNode(nums);
        System.out.println(head);

        ListNode res =(new Solution3()).removeElements(head,6);
        System.out.println(res);
    }
}


【玩转数据结构】----链表和递归_第7张图片

五、递归运行的机制:递归的微观解读

【玩转数据结构】----链表和递归_第8张图片
【玩转数据结构】----链表和递归_第9张图片
【玩转数据结构】----链表和递归_第10张图片
【玩转数据结构】----链表和递归_第11张图片

六、递归算法的调试


package com.zcw.data.recursion;

/**
 * @ClassName : Solution4
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-07-28 17:27
 */
public class Solution4 {
    public ListNode removeElements(ListNode head,int val,int depth){
        String depthString = generateDepthString(depth);
        System.out.println(depthString);
        System.out.println("Call: remove" + val +"in" +head);


        if(head ==null){
            System.out.print(depthString);
            System.out.println("Return:" +head);
            return head;
        }
        ListNode res = removeElements(head.next,val,depth+1);
        System.out.println(depthString);
        System.out.println("After remove"+ val +":"+ res);

        ListNode ret;
        if(head.val == val){
            ret = res;
        }else{
            head.next = res;
            ret = head;
        }


        System.out.println(depthString);
        System.out.println("Return:"+ ret);
        return ret;
    }

    private String generateDepthString(int depth){
        StringBuilder res = new StringBuilder();
        for(int i=0; i< depth;i++){
            res.append("--");
        }
        return res.toString();
    }

    public static void main(String[] args) {
        int[] nums ={1,2,6,3,4,5,6};
        ListNode head = new ListNode(nums);
        System.out.println(head);

        ListNode res = (new Solution4()).removeElements(head,6,0);
        System.out.println(res);
    }
}


1->2->6->3->4->5->6->NULL

Call: remove6in1->2->6->3->4->5->6->NULL
--
Call: remove6in2->6->3->4->5->6->NULL
----
Call: remove6in6->3->4->5->6->NULL
------
Call: remove6in3->4->5->6->NULL
--------
Call: remove6in4->5->6->NULL
----------
Call: remove6in5->6->NULL
------------
Call: remove6in6->NULL
--------------
Call: remove6innull
--------------Return:null
------------
After remove6:null
------------
Return:null
----------
After remove6:null
----------
Return:5->NULL
--------
After remove6:5->NULL
--------
Return:4->5->NULL
------
After remove6:4->5->NULL
------
Return:3->4->5->NULL
----
After remove6:3->4->5->NULL
----
Return:3->4->5->NULL
--
After remove6:3->4->5->NULL
--
Return:2->3->4->5->NULL

After remove6:2->3->4->5->NULL

Return:1->2->3->4->5->NULL
1->2->3->4->5->NULL

你可能感兴趣的:(算法,#,玩转算法系列,链表,leetcode)