分治算法(套娃)

 1、获取数组最大值:

#include <stdio.h>
int get_max();
int main(){
    int arr[] = {5,6,9,8,56,24,14,87,52,41,36,57,89,45};
    int max = get_max(arr, 0, 13);
    printf("max: %d\n", max);
    return 0;
}

int n = 0;
int get_max(int* arr, int left, int right){
    if(arr==NULL){
        return -1;
    }
    if(right-left == 0){
        return arr[left];
    }
    if(right-left == 1){
        if(arr[left] < arr[right]){
            return arr[right];
        }
        return arr[left];
    }
    // 划分为两部分
    int middle = (right-left)/2+left;
    n++;
    printf("!!! num: %d:  middle: %d, left: %d, right: %d : \n", n, middle, left, right);

    // 左边部分
    int max_left = get_max(arr, left, middle);
    printf("*****max_left: %d\n", max_left);

    // 右边部分
    int max_right = get_max(arr, middle+1, right);
    printf("*****max_right: %d\n", max_right);

    //比较左、右两侧的最大值,找到 [left,right] 整个区域的最大值
    if (max_left >= max_right) {
        return  max_left;
    }
    else {
        return max_right;
    }
}



// 结果分析(郁闷了半天,终于算搞明白了):
/*
!!! num: 1:  middle: 6, left: 0, right: 13 :  # 向左划分

此处为max_left的递归之中,此处称为父级递归
!!! num: 2:  middle: 3, left: 0, right: 6 :  # 向左划分
!!! num: 3:  middle: 1, left: 0, right: 3 :  # 向左划分
# 找到最左边的两组数据各自比较,此处为[5,6,9,8]
*****max_left: 6 # 比较[5,6],得出结果[6]  套娃:小小娃:进入max_left递归,得出结果,退出小小娃
*****max_right: 9 # 比较[9,8],得出结果[9] 套娃:小小娃:进入max_right递归,得出结果,退出小小娃
*****max_left: 9 # 比较[6,9] 套娃:小娃:输出结果,退出小娃

!!! num: 4:  middle: 5, left: 4, right: 6 : # 向左划分
#找到右边的两组数据各自比较,此处为[56,24,14],以下继续套娃
*****max_left: 56
*****max_right: 14
*****max_right: 56
*****max_left: 56


此处为max_right的递归之中
!!! num: 5:  middle: 10, left: 7, right: 13 :
!!! num: 6:  middle: 8, left: 7, right: 10 :
*****max_left: 87
*****max_right: 41
*****max_left: 87
!!! num: 7:  middle: 12, left: 11, right: 13 :
*****max_left: 99
*****max_right: 45
*****max_right: 99
*****max_right: 99

# 得出结果退出父级递归
max: 99
*/

2、汉诺塔问题:

  • 问题详情:自己去百度
  • 问题思路:将柱子分别定义为a,b,c三根柱
    • 将a柱上的 n-1 个圆盘移动到c柱上;(此处需要套娃细分)
    • 将a柱上遗留的 1 个圆盘移动到b柱上;
    • 将c柱上的所有圆盘移动到b柱上。(此处需要套娃细分)
    • 用分治的思路无限套娃,将步骤分为一个个3个磨盘,重复上面步骤
#include <stdio.h>

void move(int n, char start, char end){
    printf("第%d次: 从%c移至%c \n", n, start, end);
}

void hanoi(int num, char sou, char tar, char sux){
    static int n = 1;
    // 当a柱只有一个时, 直接放入b柱
    if(num==1){
        move(n++, sou, tar);
    }
    else{
        // 将a柱柱上的num-1个圆盘移至c柱(开始套娃),
        // 应为判断为a->b, 所以此时变换柱子顺序, a c b (此处套了几成娃,郁闷了大半天)
        hanoi(num-1, sou, sux, tar);

        // 将a柱上剩余的最后一个大圆盘移动到b柱上
        move(n++, sou, tar);

        // 将c柱上的num-1个圆盘移至b, 此时变换柱子顺序, c b a
        hanoi(num-1, sux, tar, sou);
    }
}

int main(){
    hanoi(3, 'A', 'B', 'C');
    printf("移动完成");
    return 0;
}

结果:

第1次: 从A移至B
第2次: 从A移至C
第3次: 从B移至C
第4次: 从A移至B
第5次: 从C移至A
第6次: 从C移至B
第7次: 从A移至B
移动完成

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值