四、递归

1.递归定义

递归,在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。也就是说,递归算法是一种直接或者间接调用自身函数或者方法的算法。

通俗来说,递归算法的实质是把问题分解成规模缩小的同类问题的子问题,然后递归调用方法来表示问题的解。

递归的基本原理

第一:每一级的函数调用都有自己的变量。

第二:每一次函数调用都会有一次返回。

第三:递归函数中,位于递归调用前的语句和各级被调用函数具有相同的执行顺序。

第四:递归函数中,位于递归调用后的语句的执行顺序和各个被调用函数的顺序相反。

第五:虽然每一级递归都有自己的变量,但是函数代码并不会得到复制。

递归的三大要素

第一要素:明确你这个函数想要干什么。先不管函数里面的代码什么,而是要先明白,你这个函数的功能是什么,要完成什么样的一件事。

第二要素:寻找递归结束条件。我们需要找出当参数为啥时,递归结束,之后直接把结果返回,请注意,这个时候我们必须能根据这个参数的值,能够直接知道函数的结果是什么。

第三要素:找出函数的等价关系式。我们要不断缩小参数的范围,缩小之后,我们可以通过一些辅助的变量或者操作,使原函数的结果不变。

递归过程

img

举例:递归数组求和

1587883873068

代码单行分析递归过程

1587888546963

package dataStructure.recursion;

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


    /**
     * 递归方法,完成数组元素求和
     * @param arr:int[]
     * @param index:int
     * @return 和
     */
    private static int sum(int[] arr,int index){
        // 最基本的问题,递归出口条件
        if(index == arr.length){
            return 0;
        }
        // 转化为更小的问题
        return arr[index] + sum(arr,index + 1);
    }

    public static void main(String[] args){
        int[] array = new int[10];
        for(int i = 0;i<10;i++){
            array[i] = i;
        }

        System.out.println(sum(array));
    }
}

2.递归解决从链表删除元素

移除链表元素

删除链表中等于给定值 val 的所有节点。

示例:

输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5

构造链表数据结构代码*******

package dataStructure.linkedlsit;

public class ListNode {
    public int val;
    public ListNode next;

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


    // 创建一个对象包含下面两个过程:1、类构造器完成类初始化(分配内存、赋予默认值)
    //                          2、类实例化(赋予给定值)
    /**
     * 传入一个数组,构造一个ListNode链表,this.val是头结点的值,this.next是除了头结点剩下的链表
     * @param arr:int[]
     */
    public ListNode(int[] arr){
        if(arr == null || arr.length == 0){
            throw new IllegalArgumentException("空");
        }
        this.val = arr[0];
        ListNode cur = this;
        for(int i = 1; i < arr.length; i++){
            cur.next = new ListNode(arr[i]);
            cur = cur.next;
        }
    }

    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();
    }
}

1587889455912

核心代码

package dataStructure.recursion;

import dataStructure.linkedlsit.ListNode;

public class Solution {

    /**
     * 递归移除head中value元素
     * @param head
     * @param value
     * @return
     */
    public static ListNode removeElements(ListNode head, int value){
        // 递归结束条件,head指向链表最后时为null
        if(head == null){
            return null;
        }
        // 缩小范围,递归调用函数本身
        head.next = removeElements(head.next, value);
        
        // head指向头元素值与传入的value相等时,移除,返回head.next;否则,不移除,返回本身
        return head.val == value ? head.next : head;
    }

    public static void main(String[] args) {
        int[] array = {1, 2, 1, 8};
        ListNode head = new ListNode(array);
        System.out.println(head.toString());
        System.out.println(removeElements(head,1));
    }
}
posted @ 2020-04-29 09:58  jacob_code  阅读(46)  评论(0)    收藏  举报