Java短期班day05

一、参数传递

总结一下:
    在java语言中,不管参数的类型,是数组类型,基本数据类型,实际参数和形式参数进行值传递的方式只有一种:
    实际参数的值   复制一份 赋值给形式参数

   参数类型是基本数据类型              值传递
   参数类型是引用数据类型(比如数组)    引用传递


    所以,实参的值,其实就有两份,调用方法中一份(实际参数),被调用方法中一份(形式参数)
    1. 当方法的参数是基本数据类型的参数的时候,
       参数有两份,同时参数对应的数据的值,也有两份

    2. 当方法的参数是引用数据类型的时候
       参数值有两份,但是两个数组类型引用变量,对应的值(数组),只有一个

 二、递归(汉诺塔问题)

package com.cskaoyan.recursion;

/*
        1.有三根杆子A,B,C。A杆上有 N 个 (N>1) 穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至 C 杆:
            a.每次只能移动一个圆盘;
            b.大盘不能叠在小盘上面。
            在汉诺塔问题中N 64 亿年
        提示:可将圆盘临时置于 B 杆,也可将从 A 杆移出的圆盘重新移回 A 杆,但都必须遵循上述两条规则。
        问:最少要移动多少次?如何移?

        递归算法的核心思想:
            在解决大规模问题的时候,可能因为问题的规模太大,无法直接解决这个问题,转而将大规模的问题,分解为一系列
            小规模的子问题,当规模小到一定程度的时候,我们可以直接解决小规模的子问题,我们只要解决这一系列小规模的子问题,
            就相当于解决了大规模的问题

            分而治之


    解决思路以N个圆盘为例:
    1. 当我们要解决N个圆盘的搬运问题,对于N个圆盘,我们可能无法一次性得到结果,
       于是,我们把N个圆盘的搬运问题, -> 最大一个的圆盘的搬运 & 最大圆盘上面的 n - 1

    2. 对于规模为1那个待搬运的最大的圆盘,直接就知道如何搬运(一步搞定)

    3. 在2的基础上,只需要,再解决 N - 1个圆盘搬运的问题

    三个盘:
    A--->C
    A--->B
    C--->B
    A--->C
    B--->A
    B--->C
    A--->C

    f(n)表示n个圆盘搬运的总次数
    f(n) = f(n - 1) + 1 + f(n - 2)
         = 2 * f(n - 1) + 1

    f(n) + 1 = 2 * f(n - 1) + 2 = 2 * (f(n-1) + 1)
    f(1) + 1 = 2

    f(n) + 1 = 2^n
    f(n) = 2^n - 1
 */
public class Demo2Hanoi {


    public static void main(String[] args) {
        int n = 4;
        hanoi(n, 'A', 'B', 'C');

        // 计算hanoi搬运的次数
        long count = countHanoi(n);
        System.out.println(count);
    }


    /*
            参数n: 表示带搬运的圆盘数量
            返回值: 表示n个圆盘搬运的总次数
     */
    public static long countHanoi(int n) {

        if (n == 1) {
            // 只有一个盘,一步就搬运完毕
            return 1;
        }

        return 2 * countHanoi(n - 1) + 1;
    }





    /*
            n:表示带待搬运的圆盘数量
            start: 这n个盘当前所在的杆的名字
            middle: 搬运过程中辅助杆的名字
            end: 这n个盘要移动到的目标杆的名字
     */
    public static void hanoi(long n, char start, char middle, char end) {
        // 定义递归出口
        if (n == 1) {
            System.out.println(start + "--->" + end );
            return;
        }

        // 将最大的盘上面n - 1盘,从start ——> middle, 以end为辅助
        hanoi(n - 1, start, end, middle);

        // 对于start杆上最大的那个盘 start —— end
        System.out.println(start + "--->" + end);

       // 将 middle杆上剩下的n-1 移动到 end杆
        hanoi(n - 1, middle, start, end);
    }




}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值