[数据结构]关于分治思想+分治寻找最大(金块问题)

分治思想是什么

分治思想指的是把一个大问题转化为多个小问题,比如以前常见的归并算法和快速排序算法都是常见的应用

直接上金块问题

问题来历:假设现在有一堆金块,要从其中找出最重和最轻的一块

一般来说寻找最大最小值我们直接使用预留max min即可,但是我们可以利用分治的思想进行处理

非递归处理的分治金块问题

处理原理:先设置好max和min,然后后续一对一对地进行比较,每次遍历中获取一对元素,然后这两个元素进行比较,得到较大和较小两个。

然后利用较大的判断是否更新max,再利用较小的判断是否更新min

(1)当元素总数为奇数个的时候,设第1个元素同时为最大最小值,然后后面的n-1个元素正常进行比较即可

(2)当元素个数为偶数个的时候,先比较一下第一个第二个元素,把max和min设置出来

具体代码如下

void findMaxAndMin(int  arr[],int length){
    int max,min;
    if(length==1){
        max=min=0;
    }else{
        if(length%2==0){//偶数个的情况
            if(arr[0]>=arr[1]){max=0;min=1;}else{max=1;min=0;}
            for(int i=2;i<=length-2;i+=2){
                if(arr[i]>arr[i+1]){
                    if(arr[i]>arr[max]){max=i;}
                    if(arr[i+1]<arr[min]){min=i+1;}
                }else{
                    if(arr[i+1]>arr[max]){max=i+1;}
                    if(arr[i]<arr[min]){min=i;}
                }
            }
        }else{         //奇数个情况
            max=min=0;
            for(int i=1;i<=length-2;i+=2){
                if(arr[i]>arr[i+1]){
                    if(arr[i]>arr[max]){max=i;}
                    if(arr[i+1]<arr[min]){min=i+1;}
                }else{
                    if(arr[i+1]>arr[max]){max=i+1;}
                    if(arr[i]<arr[min]){min=i;}
                }
            }
        }

    }
    cout<<"最大值为"<<max<<":"<<arr[max]<<"最小数"<< min<<":"<<arr[min]<<endl;
}

总结:非递归方法实际上只是分成了两组进行比较而已,或许缩减了一半工作量,但是效果并不是太明显,不像是递归那种简单明了的分治

利用递归方法寻找最大值

原理:参数:start end(均为整数)

           如果start==end,返回值为start

           否则,把字段分成两部分 返回(start,n)和(n+1,end)的中较大值

返回值为一个区间内最大的元素

代码如下

//这次仅仅寻找最大值?其实这玩意就是无限弱化版本的归并/快速排序
int findMax(int arr[],int start,int end){
    if(start==end){
        return arr[start];
    }else {
        int n=(start+end)/2;
        int a= findMax(arr,start,n);
        int b= findMax(arr,n+1,end);
        return a>b?a:b;
    }
}
//补充:关于排序算法稳定性的定义为数值一样的元素,排序前后,相对位置没有改变

第三种最小生成树算法sollin

这种算法有点分治再合并的意思?因为使用次数太少实践太难,所以基本不怎么用

这里只阐述一下原理:

(1)先把每个点都视为一个单独的图

(2)每个图的相邻边中取权重最小的一个,与对应边相邻的点形成新的子图

(3)对新生成的子图进行重复(2)操作,直到只剩一个子图为止,这个子图同时也是点生成子图,又是最小生成树

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值