四、递归
1.递归定义
递归,在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。也就是说,递归算法是一种直接或者间接调用自身函数或者方法的算法。
通俗来说,递归算法的实质是把问题分解成规模缩小的同类问题的子问题,然后递归调用方法来表示问题的解。
递归的基本原理
第一:每一级的函数调用都有自己的变量。
第二:每一次函数调用都会有一次返回。
第三:递归函数中,位于递归调用前的语句和各级被调用函数具有相同的执行顺序。
第四:递归函数中,位于递归调用后的语句的执行顺序和各个被调用函数的顺序相反。
第五:虽然每一级递归都有自己的变量,但是函数代码并不会得到复制。
递归的三大要素
第一要素:明确你这个函数想要干什么。先不管函数里面的代码什么,而是要先明白,你这个函数的功能是什么,要完成什么样的一件事。
第二要素:寻找递归结束条件。我们需要找出当参数为啥时,递归结束,之后直接把结果返回,请注意,这个时候我们必须能根据这个参数的值,能够直接知道函数的结果是什么。
第三要素:找出函数的等价关系式。我们要不断缩小参数的范围,缩小之后,我们可以通过一些辅助的变量或者操作,使原函数的结果不变。
递归过程

举例:递归数组求和

代码单行分析递归过程

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

核心代码
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));
}
}

浙公网安备 33010602011771号