您当前的位置: 首页 > 

wespten

暂无认证

  • 1浏览

    0关注

    899博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

递归的使用

wespten 发布时间:2019-06-16 11:40:15 ,浏览量:1

递归的使用

递归函数的运转

子函数调用的位置会压入系统栈,子函数调用完成时候,程序会从系统栈中找到上次在父函数中调用这个子函数的位置,然后在父函数后续继续执行。

其实递归与子函数调用没有区别,只不过调用的是自己而已。

递归本质上将原来的问题转化为更小的同一问题,小到不能再小,从而整个问题得到解决

最基本的问题,空数组的和为0,解决基本问题就可以将原问题解决

return回返回上一次父函数中断停止调用的位置

根据上面的逻辑

public class Sum {

    public static int sum(int[] arr){
        return sum(arr, 0);
    }

    // 计算arr[l...n)这个区间内所有数字的和
    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));
    }
}

递归只有两部分组成:

最基本问题需要自己求解的

另一部分 把原问题转换为更小的问题,要根据更小问题的答案构建出原问题的答案

注重递归函数本身的语意,本身就是计算所有数字的和,子逻辑本质就是要用到原来函数作为子函数调用

 

链表的天然递归性质删除递归中指定的节点

每次执行递归函数都是针对新的参数来执行逻辑

递归的微观执行步骤

 

最底的情况整个链表为空,不需要任何逻辑return null。

剩下的问题为宏观语意做的事情就是删除,把head后面的链表删除与单独判断head的头结点,判断head头结点是否为要删除的节点

public class ListNode {

    public int val;
    public ListNode next;

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

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

    public ListNode removeElements(ListNode head, int val) {

        if(head == null)
            return head;

        ListNode res = removeElements(head.next, val);
        if(head.val == val)
            return res;
        else{
            head.next = res;
            return head;
        }
        //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 Solution()).removeElements(head, 6);
        System.out.println(res);
    }
}

 

递归的调试

public class Solution {

    public ListNode removeElements(ListNode head, int val, int depth) {

        String depthString = generateDepthString(depth);

        System.out.print(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.print(depthString);
        System.out.println("After remove " + val + ": " + res);

        ListNode ret;
        if(head.val == val)
            ret = res;
        else{
            head.next = res;
            ret = head;
        }
        System.out.print(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 Solution()).removeElements(head, 6, 0);
        System.out.println(res);
    }

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

关注
打赏
1665965058
查看更多评论
立即登录/注册

微信扫码登录

0.0384s