数据结构与算法-分治法

简介: 分治法:把一片领土分解,分解为若干块小部分,然后一块块地占领征服,被分解的可以是不同的政治派别或是其他什么,然后让他们彼此异化。

分治法:


把一片领土分解,分解为若干块小部分,然后一块块地占领征服,被分解的可以是不同的政治派别或是其他什么,然后让他们彼此异化。


设计思想:


将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。


策略:


对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。


精髓:


分--将问题分解为规模更小的子问题;


治--将这些规模更小的子问题逐个击破;


合--将已解决的子问题合并,最终得出“母”问题的解;


特征:


1) 该问题的规模缩小到一定的程度就可以容易地解决


2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。


3) 利用该问题分解出的子问题的解可以合并为该问题的解;


4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。


分治法在每一层递归上都有三个步骤:


分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;


解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题;


合并:将各个子问题的解合并为原问题的解。


分治法(递归技术)


直接或间接调用自身的算法。


注意:因为递归可以替代循环,故必须有终止。否则慎用。


for (int i = 0; i <= 10; i++) {
    Log.e("SCCDemo", "Pos" + i + "返回:" + d(i));
}
//2021/5/26 功能描述:分治法(递归技术)
private int d(int pos) {
    if (pos == 0 || pos == 1) {
        return 1;
    } else {
        return d(pos - 1) + d(pos - 2);
    }
}

输出:


E/SCCDemo: Pos0返回:1===========E/SCCDemo: Pos1返回:1、


E/SCCDemo: Pos2返回:2===========E/SCCDemo: Pos3返回:3


E/SCCDemo: Pos4返回:5===========E/SCCDemo: Pos5返回:8


E/SCCDemo: Pos6返回:13==========E/SCCDemo: Pos7返回:21


E/SCCDemo: Pos8返回:34==========E/SCCDemo: Pos9返回:55



分治法(二分查找法)


二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。


要求:


1) 必须采用顺序存储结构。


2) 必须按关键字大小有序排列。


ArrayList<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 29; i++) {
    numbers.add(i);
}


/**
 * 功能描述:分治法(二分查找)
 * @param numbers   数组
 * @param a         起点
 * @param b         终点
 * @param lookUpNum 查找的数
 */
private void e(ArrayList<Integer> numbers, int a, int b, int lookUpNum) {
    if (a > b) {//查找完且未找到结果,查找失败
        Log.e("SCCDemo", "lookUpNum:" + lookUpNum + "返回:-1");
    } else {
        int mid = (a+b)/2;//找到中间点,可能导致溢出,应该使用mid=(b-a)/2+a;
        Log.e("SCCDemo", "mid:" + numbers.get(mid));
        if (numbers.get(mid) == lookUpNum) {
            Log.e("SCCDemo", "lookUpNum:" + lookUpNum + "返回:" + mid);
        } else {
            if (numbers.get(mid) > lookUpNum) {
                Log.e("SCCDemo", "查找范围:(" + a + "," + (mid - 1) + ")");
                //中间值大于lookUpNum,查找范围锁定是(a,(mid-1));
                e(numbers, a, mid - 1, lookUpNum);
            } else {
                Log.e("SCCDemo", "查找范围:(" + (mid + 1) + "," + b + ")");
                //中间值小于lookUpNum,查找范围锁定是((mid+1),b);
                e(numbers, mid + 1, b, lookUpNum);
            }
        }
    }
}


e(numbers, 0, numbers.get(numbers.size()-1), 1);


E/SCCDemo: mid:14——比较后——E/SCCDemo: 查找范围:(0,13)


E/SCCDemo: mid:6——比较后——E/SCCDemo: 查找范围:(0,5)


E/SCCDemo: mid:2——比较后——E/SCCDemo: 查找范围:(0,1)


E/SCCDemo: mid:0——比较后——E/SCCDemo: 查找范围:(1,1)


E/SCCDemo: mid:1——比较后——E/SCCDemo: lookUpNum:1返回:1


e(numbers, 0, numbers.get(numbers.size()-1), 15);


E/SCCDemo: mid:14——比较后——E/SCCDemo: 查找范围:(15,28)


E/SCCDemo: mid:21——比较后——E/SCCDemo: 查找范围:(15,20)


E/SCCDemo: mid:17——比较后——E/SCCDemo: 查找范围:(15,16)


E/SCCDemo: mid:15——比较后——E/SCCDemo: lookUpNum:15返回:15


e(numbers, 0, numbers.get(numbers.size()-1), 28);


E/SCCDemo: mid:14——比较后——E/SCCDemo: 查找范围:(15,28)


E/SCCDemo: mid:21——比较后——E/SCCDemo: 查找范围:(22,28)


E/SCCDemo: mid:25——比较后——E/SCCDemo: 查找范围:(26,28)


E/SCCDemo: mid:27——比较后——E/SCCDemo: 查找范围:(28,28)


E/SCCDemo: mid:28——比较后——E/SCCDemo: lookUpNum:28返回:28


相关文章
|
2月前
|
人工智能 自然语言处理 算法
当prompt策略遇上分治算法,南加大、微软让大模型炼成“火眼金睛”
【2月更文挑战第24天】当prompt策略遇上分治算法,南加大、微软让大模型炼成“火眼金睛”
24 2
当prompt策略遇上分治算法,南加大、微软让大模型炼成“火眼金睛”
|
5月前
|
算法
2017级《算法设计与分析》--实验1--分治算法-骨牌铺方格
2017级《算法设计与分析》--实验1--分治算法-骨牌铺方格
|
5月前
|
算法
2017级《算法设计与分析》--实验1--分治算法
2017级《算法设计与分析》--实验1--分治算法
|
3月前
|
算法
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-分治算法
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-分治算法
19 0
|
6月前
|
算法 JavaScript
分治算法
分治算法
50 0
|
7月前
|
人工智能 算法
【算法分析与设计】递归与分治策略(二)
【算法分析与设计】递归与分治策略
|
2月前
|
存储 缓存 算法
【数据结构与算法】【小白也能学的数据结构与算法】递归 分治 迭代 动态规划 无从下手?一文通!!!
【数据结构与算法】【小白也能学的数据结构与算法】递归 分治 迭代 动态规划 无从下手?一文通!!!
|
7月前
|
算法
算法:分治思想处理归并递归问题
算法:分治思想处理归并递归问题
|
7月前
|
机器学习/深度学习 算法 编译器
【算法分析与设计】递归与分治策略(一)
【算法分析与设计】递归与分治策略
|
4月前
|
存储 算法 搜索推荐
【算法系列篇】分治-归并
【算法系列篇】分治-归并