趣学算法系列-分治法

声明:本系列为趣学算法一书学习总结内容,在此推荐大家看这本算法书籍作为算法入门,
原作者博客链接,本书暂无免费电子版资源,请大家支持正版,更多实例分析请查看原书内容

第三章 分治法

  • 分治,顾名思义,分而治之。

    大问题分解成一系列规模较小的相同问题,然后逐个解决小问题,即所谓的分而治之。分治法产生的子问题与原始问题相同,只是规模减小。

  • 分治法求解的三个条件
    (1)原问题可分解为若干个规模较小的相同子问题。 分治
    (2)子问题相互独立。单个问题的解不会影响到下个问题。
    (3)子问题的解可以合并为原问题的解。 归并
  • 分治算法秘籍
    (1)分解:将要解决的问题分解为若干个规模较小、相互独立、与原问题形式相同的子问题,确保各个子问题的解具有相同的子结构
    (2)治理:求解各个子问题。由于各个子问题与原问题形式相同,只是规模较小而,
    而当子问题划分得足够小时,就可以用较简单的方法解决。 问题可以解决,直接解决,否则继续用相同的规则接着分解。
    (3)合并:按原问题的要求,将子问题的解逐层合并构成原问题的解。
    分治法的实现模式可以是递归方式,也可以是非递归方式,
  • 应用分治法的目的
    (1)通过分解问题,使无法着手解决的大问题变成容易解决的小问题
    (2)通过减小问题的规模,降低解决问题的复杂度(或计算量)

  • 分治法的难点

    分治法的难点是如何将子问题分解,并且将子问题的解合并原问题的解。
    针对不同的问题,通常有不同的分解与合并方式。
    快速排序的分解思路选择一个标兵数,小于的放到左边 大于的放到右边
    最明显的算法思路体现(Python版本)

    def quicksort(array):
    if len(array) < 2:
    return array     #基线条件:为空或只包含一个元素的数组是“有序”的
    else:
    pivot = array[0]   #递归条件
    less = [i for i in array[1:] if i <= pivot]   #由所有小于基准值的元素组成的子数组
    greater = [i for i in array[1:] if i > pivot] #由所有大于基准值的元素组成的子数组
    return quicksort(less) + [pivot] + quicksort(greater)
    print quicksort([10, 5, 2, 3])

    二分搜索的分解思路是对半缩小规模,处理左边部分,然后处理右边部分
    分治法最难也是最灵活的部分就是对问题的分解和结果的合并
    在数学上,只要是能用数学归纳法证明的问题,一般都可以应用分治法解决

  • 递归和分治联系
    问题的分解肯定不是一步到位的,反复调用,层层分解,自然导致了递归的调用。
    分治法得到的子问题和原问题是相同的,当然可以用相同的函数来解决
    区别只在于问题的规模和范围不同,可以通过参数来控制范围
    递归同时也可以该用循环的方式,特别是尾递归(此部分后续会有单独的分析)
  • 贪心算法的典型应用
            最优装载问题
            背包问题

  • 实际案例分析-最优装载问题

    • 问题情景

      一天晚上,我们在家里看电视,某大型娱乐节目在玩猜数游戏。主持人在女嘉宾的手心上写一个 10 以内的整数,让女嘉宾的老公猜是多少,而女嘉宾只能提示大了,还是小了,并且只有 3 次机会

    • 问题分析

      从问题描述来看,如果是 n 个数,那么最坏的情况要猜 n 次才能成功,其实我们没有必要一个一个地猜,因为这些数是有序的,它是一个二分搜索问题。我们可以使用折半查找的策略,每次和中间的元素比较,如果比中间元素小,则在前半部分查找(假定为升序),如果比中间元素大,则去后半部分查找。

    • 算法设计

      问题描述:给定 n 个元素,这些元素是有序的(假定为升序),从中查找特定元素 x。
      算法思想:将有序序列分成规模大致相等的两部分,然后取中间元素与特定查找元素 x
      进行比较,
      如果 x 等于中间元素,则查找成功,算法终止;
      如果 x 小于中间元素,则在序列的前半部分继续查找,即在序列的前半部分重复分解和治理操作;
      否则,在序列的后半部分继续查找,即在序列的后半部分重复分解和治理操作

      算法设计:用一维数组 S[]存储该有序序列,设变量 low 和 high 表示查找范围的下界和上界, middle 表示查找范围的中间位置, x 为特定的查找元素。

    • 完美图解
      用分治法在有序序列( 5, 8, 15, 17, 25, 30, 34, 39, 45, 52, 60)中查找元素 17。
      (1)数据结构。用一维数组 S[]存储该有序序列, x=17,如图 3-2 所示

      (2)初始化。 low=0, high=10,计算 middle=(low+high)/2=5,如图 3-3 所示。

      (3)将 x 与 S[middle]比较。我们在序列的前半部分查找,搜索的范围缩小到子问题 S[0..middle−1],令 high=middle−1,如图 3-4 所示

      (4)计算 middle=( low+high) /2=2,如图 3-5 所示。

      (5)将 x 与 S[middle]比较。 x=17>S[middle]=15,我们在序列的后半围缩小到子问题S[middle+1..low],令 low=middle+1,如图 3-6 所示

      (6)计算 middle=( low+high) /2=3,如图 3-7 所示

      (7)将 x 与 S[middle]比较。 x=17=S[middle]=17,查找成功,算法结束。

  • 伪代码详解

int BinarySearch(int n,int s[],int x){int low=0,high=n-1; //low 指向数组的第一个元素, high 指向数组的最后一个元素while(low<=high) //设置判定条件{int middle=(low+high)/2;//计算 middle 值(查找范围的中间值)if(x==s[middle]) //x 等于 s[middle],查找成功,算法结束return middle;else if(x<s[middle]) //x 小于 s[middle],则从前半部分查找high=middle-1;else //x 大于 s[middle],则从后半部分查找low=middle+1;}return -1;
}
  • 实战演练
    //program 3-1#include <iostream>#include <cstdlib>#include <cstdio>#include <algorithm>using namespace std;const int M=10000;int x,n,i;int s[M];int BinarySearch(int n,int s[],int x){int low=0,high=n-1; //low 指向数组的第一个元素, high 指向数组的最后一个元素while(low<=high){int middle=(low+high)/2; //middle 为查找范围的中间值if(x==s[middle]) //x 等于查找范围的中间值,算法结束return middle;else if(x<s[middle]) //x 小于查找范围的中间元素,则从前半部分查找high=middle-1;else //x 大于查找范围的中间元素,则从后半部分查找low=middle+1;}return -1;}int main(){cout<<"请输入数列中的元素个数 n 为: ";while(cin>>n){cout<<"请依次输入数列中的元素: ";for(i=0;i<n;i++)cin>>s[i];sort(s,s+n);cout<<"排序后的数组为: ";for(i=0;i<n;i++){cout<<s[i]<<" ";}cout<<endl;cout<<"请输入要查找的元素: ";cin>>x;i=BinarySearch(n,s,x);if(i==-1)cout<<"该数列中没有要查找的元素"<<endl;elsecout<<"要查找的元素在第"<<i+1<<"位"<<endl;}return 0;}
  • 算法时间复杂度分析

(1)时间复杂度:首先需要进行排序,调用 sort 函数,进行排序复杂度为 O(nlogn),如
果数列本身有序,那么这部分不用考虑。二分查找排序O(logn)
(2)空间复杂度:程序中变量占用了一些辅助空间,这些辅助空间都是常数阶的,因此
空间复杂度为 O(1)

趣学算法系列-分治法相关推荐

  1. 趣学算法系列-回溯法

    趣学算法系列-回溯法 声明:本系列为趣学算法一书学习总结内容,在此推荐大家看这本算法书籍作为算法入门, 原作者博客链接,本书暂无免费电子版资源,请大家支持正版 第五章 回溯法 回溯法是一种选优搜索法, ...

  2. 趣学算法系列-动态规划

    趣学算法系列-动态规划 声明:本系列为趣学算法一书学习总结内容,在此推荐大家看这本算法书籍作为算法入门, 原作者博客链接,本书暂无免费电子版资源,请大家支持正版,更多实例分析请查看原书内容 第四章 动 ...

  3. 趣学算法系列-贪心算法

    趣学算法系列-贪心算法 声明:本系列为趣学算法一书学习总结内容,在此推荐大家看这本算法书籍作为算法入门, 原作者博客链接,本书暂无免费电子版资源,请大家支持正版,更多的案例分析请查看原书内容. 第二章 ...

  4. 趣学算法系列-分支限界法

    趣学算法系列-分支限界法 声明:本系列为趣学算法一书学习总结内容,在此推荐大家看这本算法书籍作为算法入门, 原作者博客链接,本书暂无免费电子版资源,请大家支持正版 第六章 分支限界法 在树搜索法中,从 ...

  5. 《趣学算法(第2版)》读书笔记 Part 1 :如何高效学习算法

    14天阅读挑战赛 系列笔记链接 <趣学算法(第2版)>读书笔记 Part 1 :如何高效学习算法 <趣学算法(第2版)>读书笔记 Part 2 :算法入门 <趣学算法(第 ...

  6. 【趣学算法】-Day2-贪心算法

    14天阅读挑战赛 努力是为了不平庸~ 算法学习有些时候是枯燥的,这一次,让我们先人一步,趣学算法!欢迎记录下你的那些努力时刻(算法学习知识点/算法题解/遇到的算法bug/等等),在分享的同时加深对于算 ...

  7. 《趣学算法(第2版)》读书笔记 Part 4 :贪心算法基础(操作)

    14天阅读挑战赛 系列笔记链接 <趣学算法(第2版)>读书笔记 Part 1 :如何高效学习算法 <趣学算法(第2版)>读书笔记 Part 2 :算法入门 <趣学算法(第 ...

  8. 序列复杂度怎么看_《趣学算法》作者又一力作上架,再分享您一篇算法复杂度...

    不知道读者们有没有看过陈小玉的<趣学算法>这本书,该书在出版后受到广大读者一致好评,在一年内重印了10次,并输出了繁体版的版权.不知道读过这本书的朋友们感觉第一本怎么样?欢迎留言给我们.接 ...

  9. 信号处理趣学D0——系列专栏的说明与目录

    信号处理趣学专栏是小虎同学在学习测试技术的时候做的一系列笔记和心得的集合,定位是利用仿真软件(主要是MATLAB)带大家领略信号处理的一些基本概念. 目录 信号处理趣学D0--系列专栏的说明与目录 信 ...

最新文章

  1. win10java插件删除不掉_win10系统卸载电脑上的java的操作方法
  2. 真正的人工智能不应该只有统计学
  3. Visual Studio2005无法启动web调试的真正原因
  4. python自带的shell是什么-python中执行shell的两种方法总结
  5. C+ 轮融资发布会抽奖名单公布,还有 20 万礼物正在路上
  6. Python之路【第十篇】:索引与切片的不同
  7. Ironic 安装和配置详解
  8. python 参数_Python命令行参数(七)
  9. sigmoid函数手动求导
  10. c语言中int(*t) n,C语言基础知识(下)
  11. centos下 将(jgp、png)图片转换成webp格式
  12. 《那些年啊,那些事——一个程序员的奋斗史》三
  13. 相机标定示例(OpenCV /C++ /matlab工具箱TOOLBOX_calib)
  14. 阿里云ACP考试模拟题一
  15. 2020高交会第二十二届中国国际高新技术成果交易会
  16. anaconda启动 (base)环境问题
  17. 微信小程序项目源码ssm校园跑腿+后台管理系统|前后分离VUE含论文+PPT+源码
  18. 迅睿CMS 万网虚拟主机无法连接数据库
  19. 微信小程序(第七章)- 搜索框的实现
  20. VTK笔记-几何图形-点vtkPoints构成的空间曲线

热门文章

  1. JavaScript深拷贝封装
  2. Matlab自制Colorbar(二)
  3. Showmodal与Show的区别
  4. SDUSTOJ:Problem D: 儿童绘画游戏
  5. 教师基本功训练计算机,2017年中小学教师基本功训练计划
  6. asp汽车装潢用品销售网站
  7. 怎样刷百度相关搜索-搜索枪手
  8. 新人怎么入门游戏建模?从哪一个软件开始学习?
  9. Ubuntu 18.04 Desktop 下的基础操作,零基础入门
  10. 夸克浏览器禁止访问怎么回事?