• Java递归算法(Java算法和数据结构总结笔记)[6/20]


    1、递归是什么

    递归是什么,简单的说递归就是循环调用。

    递归算法(英语:recursion algorithm)在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。

    解决的问题:

    • 数据的定义是按递归定义的。
    • 问题解法按递归算法实现。
    • 数据的结构形式是按递归定义的。如二叉树、广义表等

    2、递归算法的使用

    (1)使用的递归求和

    1. /**
    2. * 使用递归求和
    3. * @param arr 集合
    4. * @return 返回的和
    5. */
    6. public static int sum(int[] arr){
    7. return sum(arr,0);
    8. }
    9. public static int sum(int[] arr, int index){
    10. // 判断是否是最后一个元素
    11. if (index == arr.length){
    12. return 0;
    13. }
    14. // 递归求值
    15. return arr[index] + sum(arr, index + 1);
    16. }

    (2)解析递归的调用过程

    1、sum() 方法递归调用,拿到最后一个值后,开始返回,并累加值,即 sum(arr, 2)返回值为0, 

    sum(arr, 1)返回值为0+10,以此累加求和。

    3、使用递归删除链表中的值

    (1)创建 ListNode 类

    1. /**
    2. * @version 1.0
    3. * @description: TODO 链表
    4. */
    5. public class ListNode {
    6. public int val;
    7. public ListNode next;
    8. public ListNode(int val){
    9. this.val = val;
    10. }
    11. // 把数组中的值转换成链表的形式
    12. public ListNode(int[] arr) {
    13. if (arr == null || arr.length == 0){
    14. throw new IllegalArgumentException("集合不能为空");
    15. }
    16. this.val = arr[0];
    17. ListNode cur = this;
    18. for (int i = 1; i < arr.length; i++) {
    19. cur.next = new ListNode(arr[i]);
    20. cur = cur.next;
    21. }
    22. }
    23. @Override
    24. public String toString() {
    25. StringBuilder res = new StringBuilder();
    26. res.append("head [ ");
    27. ListNode cur = this;
    28. while (cur != null){
    29. res.append(cur.val + "->");
    30. cur = cur.next;
    31. }
    32. res.append("NULL ]");
    33. return res.toString();
    34. }
    35. }

    (2)使用递归的方式删除链表中的一个节点

    1. /**
    2. * 使用递归的方法删除节点
    3. * @param head 头节点
    4. * @param val 值
    5. * @return 返回值
    6. */
    7. public ListNode removeElementByRecursion(ListNode head, int val){
    8. if (head == null){
    9. return null;
    10. }
    11. head.next = removeElementByRecursion(head.next, val);
    12. return head.val == val ? head.next : head;
    13. }

    如果不使用递归:

    1. /**
    2. * 使用while循环的方法删除节点
    3. * @param head 头节点
    4. * @param val 值
    5. * @return 返回值
    6. */
    7. public ListNode removeElement(ListNode head, int val){
    8. // 创建一个虚拟头节点,方便后续遍历
    9. ListNode dummyHead = new ListNode(-1);
    10. dummyHead.next = head;
    11. // 从虚拟节点开始遍历
    12. ListNode prev = dummyHead;
    13. // 判断虚拟头节点的下一个节点的值是否为空
    14. while (prev.next != null){
    15. // 如果节点的值等于要删除的值,则把下下个节点的值的指向赋给当前
    16. if (prev.next.val == val){
    17. prev.next = prev.next.next;
    18. }else {
    19. // 继续下一个值的遍历
    20. prev = prev.next;
    21. }
    22. }
    23. // 返回虚拟头节点的下一个值,即实际的值
    24. return dummyHead.next;
    25. }

    由此可见,使用递归的方式删除节点,代码会简洁很多。

    4、打印输出递归的调用过程

    1. /**
    2. * 打印递归的调用详情
    3. * @param head 头节点
    4. * @param val 值
    5. * @param depth 深度
    6. * @return 返回值
    7. */
    8. public ListNode removeElementByRecursionInfo(ListNode head, int val, int depth){
    9. String depthStr = generateDepthStr(depth);
    10. System.out.print(depthStr);
    11. System.out.println("调用了【remove】方法,删除:" + val + "在:" + head + "中!");
    12. if (head == null){
    13. System.out.print(depthStr);
    14. System.out.println("Return:" + head);
    15. return head;
    16. }
    17. ListNode res = removeElementByRecursionInfo(head.next, val, depth + 1);
    18. System.out.print(depthStr);
    19. System.out.println("执行后【remove】方法,删除:" + val + "现在:" + res);
    20. ListNode ret;
    21. if (head.val == val){
    22. ret = res;
    23. }else {
    24. head.next = res;
    25. ret = head;
    26. }
    27. System.out.print(depthStr);
    28. System.out.println("现在返回的值是:" + ret);
    29. return ret;
    30. }
    31. private String generateDepthStr(int depth) {
    32. StringBuilder builder = new StringBuilder();
    33. for (int i = 0; i < depth; i++) {
    34. builder.append("--");
    35. }
    36. return builder.toString();
    37. }

    打印详情:

     

  • 相关阅读:
    Python:实现merge sort归并排序算法(附完整源码)
    21款奔驰S400L升级HUD抬头显示 不用低头也能看见仪表信息
    干货 | Elasticsearch Java 客户端演进历史和选型指南
    潘多尼亚精灵 VoxEdit 创作大赛
    java计算机毕业设计消防安全应急培训管理平台源码+系统+数据库+lw文档+mybatis+运行部署
    基于yolov5的草莓成熟度检测系统,可进行图像目标检测,也可进行视屏和摄像检测(pytorch框架)【python源码+UI界面+功能源码详解】
    Java面试题
    什么是云原生?土生土长?
    Hikvison对接iSecure Center时获取Appkey和Secert、不显示API网关、预览时提示网络请求失败
    PyTorch 模型性能分析和优化 — 第 1 部分
  • 原文地址:https://blog.csdn.net/amosjob/article/details/127760370