IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 算法设计和分析 ② 分治和递归 -> 正文阅读

[数据结构与算法]算法设计和分析 ② 分治和递归

第二章 分治和递归

2.1 递归

2.1.1 递归的定义

? ? ? ? ① 程序调用自身的编程技巧称为递归。

? ? ? ? ② 递归的基本思路:将一个大型问题转化为一些与原问题相似的规模较小的问题来求解。

? ? ? ? ③ 如果函数调用他本身,那么他就是递归的。

2.1.2 递归的应用场景

? ? ? ? ① 问题的定义是递归的:例如斐波拉契数列。

? ? ? ? ② 解决问题采用的数据结构是递归定义的:例如二叉树的遍历

? ? ? ? ③ 问题的求解过程是递归的:例如汉诺塔问题

2.1.3 递归式

? ? ? ? 递归式是用于描述递归函数的数学公式,斐波拉契数列便是一个典型的例子,举例如下:

????????

????????其满足:

????????① 第一式给出了函数的初始值,称为边界条件

? ? ? ? ② 第二式用较小的自变量函数值来描述大自变量的函数值,称为递归方程

? ? ? ? ③ 递归方程和边界条件是递归的两个基本要素

2.1.4 斐波拉契数列的简单实现

? ? ? ? ① 程序实现如下:

long int fib(int n) {
	// 边界条件
	if (n <= 1) 
	{
		return 1;
	}
	else
	{
		// 递归方程
		return fib(n - 1) + fib(n - 2);
	}
}

??????② 以n = 4,即fib(4)程序运行如下:

?

2.1.5 递归的使用条件

? ? ? ? ① 原始问题可以分解成相似的子问题

? ? ? ? ② 子问题的规模小于原始问题

? ? ? ? ③ 递归函数必须有某些类型的终止条件

2.1.6 递归的优缺点

????????

递归优点结构清晰,易于理解,容易用数学归纳法来证明算法正确性
递归缺点

执行时多次调用自身,运行效率较低,所耗费的时间空间都比非递归算法多。

某些运算步骤可能重复计算,进一步降低效率

2.2 分治

2.2.1 分治的设计思想

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

?

????????分治模式在每一层递归上的步骤。

? ? ? ? ① 分解(Divide): 将一个难以直接解决的大问题,分割成一些规模较小的子问题,这些子问题相互独立,且与原问题相同。

? ? ? ? ②求解(Conquer):递归求解子问题,若问题足够小则直接求解

? ? ? ? ③合并(Combine):将各个子问题的解合并得到原问题的解。

2.2.2 二分搜索法的简单实现

????????

// a[]为已经升序排列好的数组,x为查找的目标,left和right为当前分区的左右数组下标
int BinarySearch(int a[], int x, int left, int right) {
    // right >= left 表示还有数据未检索
    while (right >= left) {
        // 获取升序排列数组的中间值的下标
        int mid = (left + right) / 2;
        // 如果目标值与数组值相等,返回数组下标
        if (x == a[mid]) return mid;
        // 如果目标值小于数组值,左边数组下标不变,右边数组下标选取mid - 1
        if (x < a[mid]) right = mid - 1;
        // 如果目标值大于数组值,右边数组下标不变,左边数组下标选取mid + 1
        else left = mid + 1;
    }
    // 没有找到对应元素返回-1
    return -1;
}

? ? ? ? ?① 数组a[ i ]为排序好的升序数组,如果传入数组为乱序,则不可使用此方法。

2.2.3 分治法的适用条件

? ? ? ? ① 问题缩小到一定程度可以容易的解决

? ? ? ? ② 问题可以分解成若干规模较小的相同问题

? ? ? ? ③ 利用子问题的解可以合并得到原始问题的解

? ? ? ? ④ 问题所分解出的各个子问题是相互独立的,子问题不包含公共子问题

2.2.4 递归复杂度判定定理

参考博客1:重谈主定理(master定理)及其证明 - Jayun - 博客园

参考博客2:【Master Theorem主定理】递归时间复杂度分析_白马金羁侠少年的博客-CSDN博客

?其可简化为:

????????

其中,n为问题规模,a为递推的子问题数量,n/b为每个子问题规模,O( n^d )为递推以外进行的计算工作量。

对于其时间复杂度T(n)的有:

?举例如下:

?此时 a = 3, b = 2, d = 1, 即有 a = 3 > b^d = 2, 时间复杂度T(n) = O(n^log3) = O(n^1.59)

?此时a = 8, b = 2, d = 2,即有 a = 8 > b^d = 4, 时间复杂度T(n) = O(n^log8) = O(n^3)

需要注意的是在时间复杂度计算中,一般以2为底的对数简写为log。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-27 13:04:40  更:2021-10-27 13:05:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:48:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码