学习笔记之递归算法

兔子问题

初始兔子有一对,两个月后,第三个月开始生出一对兔子,生出来的兔子两个月后成熟,第三个月继续生兔子,如果兔子都不死,计算兔子某月份的对数
递归

static int recursionRabbit( int b) {
        if (b<3)
        return 1;
        return recursionRabbit(b-1)+recursionRabbit(b-2);
    }

非递归

   static int rabbit(int a){
   //c是总数,a1是成熟的可以生的兔子,a2是不能生的兔子,这里a1是i=3时的个数
        int c=0;
        int a1=1;
        int a2=0;
        for (int i=1;i<=a;i++){
            if (i<3){
                c=1;
            }else{
            //c是上个月成熟的兔子
                c=a1;
            //此时上个月出生的兔子下个月就可以生了,所以并入成熟的里面,但不参与生兔子  
                a1=a2+a1;
                a2=c;
            //这时c才是本月所有的兔子
                c=a1+a2;
            }
    }
        return c;
}

轮盘枪决

n个罪犯,围成圈从一报数,枪决单数,剩下一人
非递归

static void executed(List a){
//判断上一轮是否为奇数,是就更改初始值奇偶
        boolean b1=false;
        while (true){
        int i=1;
        if (b1)
            i=2;
         int k=a.size();
         //迭代删除
        Iterator iterator=a.iterator();
        while (iterator.hasNext()){
            iterator.next();
            if (i%2!=0) {
                iterator.remove();
            }
            i++;
        }
        //System.out.println(a);
        if (a.size()<=1) {
            System.out.println(a);
            break;
        }
        if (k%2==1){
         b1=!b1;
            System.out.println(a);
        }else
            System.out.println(a);
         }
    }

递归

    static void executed(List count,int i){
    //以为递归是调用自身,所有每次删除长度都会减小一,所以i自增一可以只删除奇数位置的值
        if (i>count.size()){
            i-=count.size();
            System.out.println(count);
        }
        //System.out.println(count);
        //System.out.println(i);
        count.remove(i-1);
        if (count.size()>1)
        Executed(count,++i);
        else
            System.out.println(count);
    }

河内之塔

三根柱子,第一根上有n个圆盘,圆盘从小的只能在大的上面,移动圆盘到第三根柱子上
递归

 static void hanoi(int n, char A, char B, char C) {
       //调用自身,将连续的视为一个整体遵循a->c,(b-c),a->b,c->b
        if(n == 1) {
            System.out.printf("移动 %d 从 %c 到 %c\n", n, A, C);
//            System.out.printf("%c, %c ,%c\n", A, B, C);

        }
        else {
            hanoi(n-1, A, C, B);
            System.out.printf("移动 %d 从 %c 到 %c\n", n, A, C);
//            System.out.printf("%c, %c ,%c\n", A, B, C);
            hanoi(n-1, B, A, C);
        }
    }

非递归

 static boolean move(List<Integer> a, List<Integer> b, char c, char d) {
        if (a == null || a.size() == 0) {
            return false;
        }
        System.out.println("移动 " + a.get(a.size() - 1) + " 从 " + c + a + " 到 " + d + b);
        if (b == null || b.size() == 0) {
            b.add(a.get(a.size() - 1));
            a.remove(a.size() - 1);
            System.out.println(" 从 " + c + a + " 到 " + d + b);
            return true;
        }
        if (a.get(a.size() - 1) > b.get(b.size() - 1)) {
            return false;
        }
        b.add(a.get(a.size() - 1));
        a.remove(a.get(a.size() - 1));
        System.out.println(" 从 " + c + a + " 到 " + d + b);
        return true;
    }
    static boolean top(List<Integer> a) {
        if (a == null || a.size() == 0)
            return false;
        if (a.get(a.size() - 1) == 1) {
            return true;
        }
        return false;
    }
    static int getDiskSize(List<Integer> a) {
        return a.get(a.size() - 1);
    }
    static void start(int n) {
        List<Integer> a = new ArrayList();
        List<Integer> b = new ArrayList();
        List<Integer> c = new ArrayList();
        char aa = 'A';
        char bb = 'B';
        char cc = 'C';
        //移动的次数
        int asd = 0;
        list(n, a);
        System.out.println(a.size());
//遵循规律移动顶端元素,移动非顶端元素,按照规律进行移动
        while (true) {
            //判断顶端元素,移动
            if (top(a)) {
                move(a, c, aa, cc);
                asd += 1;
            } else if (top(b)) {
                move(b, a, bb, aa);
                asd += 1;
            } else if (top(c)) {
                move(c, b, cc, bb);
                asd += 1;
            }
            //以下是对非top的判断和移动
            if (top(a)) {
                if (b.size() == 0) {
                    move(c, b, cc, bb);
                    asd += 1;
                } else if (c.size() == 0) {
                    move(b, c, bb, cc);
                    asd += 1;
                } else if (getDiskSize(b) > getDiskSize(c)) {
                    move(c, b, cc, bb);
                    asd += 1;
                } else {
                    move(b, c, bb, cc);
                    asd += 1;
                }
            } else if (top(b)) {
                if (a.size() == 0) {
                    move(c, a, cc, aa);
                    asd += 1;
                } else if (c.size() == 0) {
                    move(a, c, aa, cc);
                    asd += 1;
                } else if (getDiskSize(a) > getDiskSize(c)) {
                    move(c, a, cc, aa);
                    asd += 1;
                } else {
                    move(a, c, aa, cc);
                    asd += 1;
                }
            } else if (top(c)) {
                if (a.size() == 0) {
                    move(b, a, bb, aa);
                    asd += 1;
                } else if (b.size() == 0) {
                    move(a, b, aa, bb);
                    asd += 1;
                } else if (getDiskSize(a) > getDiskSize(b)) {
                    move(b, a, bb, aa);
                    asd += 1;
                } else {
                    move(a, b, aa, bb);
                    asd += 1;
                }
            }
            if (c.size() >= n) {
                System.out.println(asd-1);
                break;
            }
        }
    }

未完待续

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值