数据结构(6):递归调用原理以及调试

一、实现功能

递归算法实现原理,通过代码以及图解的方式,解释递归过程,从而使对递归算法有更加清晰和深入的理解。

二、递归基本流程

1.基本步骤

(1)求解原始问题转换为最小最基本的问题
(2)把原始问题转换为更小的问题

2.简单实现:数组加和

package com.DataStructures._05Recursion;

/**
 * Created by Administrator on 2019/11/19.
 * 递归实现加和
 */
public class RecSum {
    /**
     * 0.客户端函数
     * @param array
     * @return
     */
    public static int sum(int[] array){

        return sum_exe(array,0);
    }

    /**
     * 0-1.计算array[l,n)这个区间内的所有数字和
     * @param array
     * @param l
     * @return
     */
    private static int sum_exe(int[] array ,int l){
        //第一步:求解最基本的问题
        if (l==array.length)
            return 0;
        //第二步:把原始问题转化为更小的问题
        return array[l]+sum_exe(array,l+1);
    }

    public static void main(String[] args) {
        int[] nums={1,2,4,5,76,45,34};
        System.out.println(sum(nums));
    }
}

三、递归实现和理解

1.删除包含指定值的链表节点

package com.DataStructures._05Recursion;

//方法一:递归法,删除链表指定值的节点
class RecRemoveListImprove {

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


}

2.理解
(1)针对原始代码每一行进行编号

(2)原始链表为:6-》7-》8-》null,包含三个节点。

(3)代码功能:删除节点值为7的节点。
-》从第一次调用函数,一直到最后一次调用过程


-》最后一次调用,返回值到最初调用

-》删除了值为7的节点,最终链表节点为:6-》8-》null

四、递归算法调试方法

1.添加标记量

(1)打印深度

//依据运行深度,打印对应长度的==符号
private String generateDepthString(int depth){
    StringBuilder res=new StringBuilder();
    for (int i=0;i<depth;i++){
        res.append("==");
    }
    return res.toString();
}

(2)打印当前链表

System.out.println("Before remove "+ val+ ": "+ head);

2.代码

package com.DataStructures._05Recursion;

import java.util.List;

/// Leetcode 203. Remove Linked List Elements
/// https://leetcode.com/problems/remove-linked-list-elements/description/
//方法一:递归法,删除链表制定节点
//调试递归函数改进
class RecRemoveListDebug {


    //添加递归深度参数,查看递归流程
    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 null;
            return head;
        }
//        ListNode res=removeElements(head.next,val);
//        if(head.val==val){
//            return res;
//        }else {
//            head.next=res;
//            return head;
//        }
        //简化代码
//        head.next=removeElements(head.next,val,depth+1);

        ListNode results=removeElements(head.next,val,depth+1);
        //如果该节点包含指定值,在删除指定节点之前
        System.out.print(depthString);
        System.out.println("Before remove "+ val+ ": "+ head);

        //在删除指定节点之后
        System.out.print(depthString);
        System.out.println("After remove "+ val+ ": "+ results);

        ListNode ret;
        if (head.val==val){
            ret=results;
        }else {
            head.next=results;
            ret=head;
        }
        System.out.print(depthString);
        System.out.println("Return: "+ ret);


//        return head.val==val?head.next:head;
        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,3,4,6,43,23};
        ListNode head=new ListNode(nums);
        System.out.println(head);

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

}

4.效果
 

1->2->3->4->6->43->23->Null
==Call: remove 6 in 1->2->3->4->6->43->23->Null
====Call: remove 6 in 2->3->4->6->43->23->Null
======Call: remove 6 in 3->4->6->43->23->Null
========Call: remove 6 in 4->6->43->23->Null
==========Call: remove 6 in 6->43->23->Null
============Call: remove 6 in 43->23->Null
==============Call: remove 6 in 23->Null
================Call: remove 6 in null
================Return: null
==============Before remove 6: 23->Null
==============After remove 6: null
==============Return: 23->Null
============Before remove 6: 43->23->Null
============After remove 6: 23->Null
============Return: 43->23->Null
==========Before remove 6: 6->43->23->Null
==========After remove 6: 43->23->Null
==========Return: 43->23->Null
========Before remove 6: 4->6->43->23->Null
========After remove 6: 43->23->Null
========Return: 4->43->23->Null
======Before remove 6: 3->4->43->23->Null
======After remove 6: 4->43->23->Null
======Return: 3->4->43->23->Null
====Before remove 6: 2->3->4->43->23->Null
====After remove 6: 3->4->43->23->Null
====Return: 2->3->4->43->23->Null
==Before remove 6: 1->2->3->4->43->23->Null
==After remove 6: 2->3->4->43->23->Null
==Return: 1->2->3->4->43->23->Null
1->2->3->4->43->23->Null


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值