青岛大学_王卓老师【数据结构与算法】Week05_11_栈与递归_学习笔记

本文是个人学习笔记,素材来自青岛大学王卓老师的教学视频。

一方面用于学习记录与分享,

另一方面是想让更多的人看到这么好的《数据结构与算法》的学习视频。

如有侵权,请留言作删文处理。

课程视频链接:

数据结构与算法基础–第05周11–3.4栈和递归

📚 【Week05】11_栈与递归

递归的定义

(1) 若一个对象部分地包含它自己,或用它自己给自己定义,则称这个对象是递归的。

(2) 若一个过程直接或间接地调用自己,则称这个过程是递归的过程。

例如:递归求 n 的阶乘

long Fact(long n){if(n == 0)return 1;elsereturn (n * Fact(n-1));
}

以下三种情况尝尝用到递归方法

(1) 递归定义的数学函数

阶乘函数

在这里插入图片描述

2 阶 Fibonaci 数列

在这里插入图片描述

(2) 具有递归特性的数据结构

在这里插入图片描述

(3) 可递归求解的问题

迷宫问题

Hanoi 塔问题

递归问题——用分治法求解

分治法

对于一个较为复杂的问题,能够分解成几个相对简单的且解法相同或类似的子问题来求解

必备的三个条件

(1) 能够将一个问题转变为一个新问题,且新问题与原问题的解法相同或类同,不同的仅是处理的对象,且这些处理对象是变化且有规律的

(2) 可以通过上述转化而使问题简化

(3) 必须有一个明确的递归出口,或称递归的边界

分治法求解递归问题算法的一般形式
void p(参数表){if(递归结束条件)可直接求解步骤;	// -- 基本项elsep(较小的参数);	 // -- 归纳项
}

例如

long Fact(long n){if(n == 0)return 1;					// -- 基本项elsereturn (n * Fact(n-1));		// -- 归纳项
}
函数调用过程

调用前,系统完成:

(1) 将实参,返回地址等传递给被调用函数

(2) 为被调用函数的局部变量分配存储区

(3) 将控制转移到被调用函数的入口

调用后,系统完成:

(1) 保存被调用函数的计算结果

(2) 释放被调用函数的数据区

(3) 依照被调用函数保存的返回地址将控制转移到调用函数

当多个函数构成嵌套调用时:
int main(void){...;y = fact(3);...;       
}double fact(int n){...;z = mypow(3.5, 2);...;
}double mppow(double x, int n){...;
}

遵循后调用的先返回

求解阶乘 n ! 的过程
long Fact(long n){if(n == 0)return 1;elsereturn (n * Fact(n-1));
}

在这里插入图片描述

递归函数调用的实现

在这里插入图片描述

进行 fact(4) 调用的系统栈的变化状态

在这里插入图片描述

递归的优缺点

优点:结构清晰,程序易读

缺点:每次调用要生成工作记录,保存状态信息,入栈;返回时要出栈,恢复状态信息。时间开销大。

递归 -> 非递归

方法1:尾递归、单向递归 -> 循环结构

方法2:自用模拟系统的运行时栈

尾递归 -> 循环结构
long Fact(long n){if(n == 0)return 1;elsereturn (n * Fact(n-1));
}

转换为循环

long Fact(long n){t = 1;for(int i=1; i<n; i++){t = t*i;}return t;
}
单向递归 -> 循环结构

虽然有一处以上的递归调用语句,但各次递归调用语句的参数只和主调函数有关,相互之间参数无关,

并且这些递归调用语句处于算法的最后

// Fibonacci 数列
long Fib(long n){if(n == 1 || n == 2)return 1;else return (Fib(n-1) + Fib(n-2));
}

转换为

// Fibonacci 数列
long Fib(long n){if(n == 1 || n == 2)return 1;else {t1 = 1;t2 = 1;for(i=3; i<n; i++){t3 = t1 + t2;t1 = t2;t2 = t3;}return t3;}
}
借助栈改写递归

(1) 递归程序在执行时,需要系统提供栈来实现

(2) 仿照递归算法执行过程中递归工作栈的状态变化可写出相应的非递归程序

(3) 改写后的非递归算法与原来的递归算法相比,结构不够清晰,可读性较差,有的还需要经过一系列优化

了解内容

借助栈改写递归的方法

(1) 设置一个工作栈存放递归工作记录 (包括实参、返回地址及局部变量等)。

(2) 进入非递归调用入口 (即被调用程序开始处)将调用程序传来的实在参数和返回地址入栈(递归程序不可以作为主程序,因而可认为初始是被某个调用程序调用)。

(3) 进入递归调用入口: 当不满足递归结束条件时,逐层递归,将实参、返回地址及局部变量入栈,这一过程可用循环语句来实现一模拟递归分解的过程。

(4) 递归结束条件满足,将到达递归出口的给定常数作为当前的函数值。

(5) 返回处理: 在栈不空的情况下,反复退出栈顶记录,根据记录中的返回地址进行题意规定的操作,即逐层计算当前函数值,直至栈空为止一模拟递归求值过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/480.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[sqoop]导入数据

一、覆盖导入 例如维度表&#xff0c;每次导入的数据需要覆盖上次导入的数据。 hive-overwrite参数&#xff1a;实现覆盖导入 hive-import参数&#xff1a;表示向hive表导入 hive-table参数&#xff1a;指定目标hive库表 sqoop import \ --connect jdbc:mysql://hadoop1:3…

哈希表的原理

哈希概念 线性表、树结构的查找方式都是以关键字的比较为基础&#xff0c;查找效率比较低&#xff0c;顺序表的时间复杂度是O&#xff08;n&#xff09;&#xff0c;平衡树中为树的高度&#xff0c;即O&#xff08;logn&#xff09;&#xff0c;搜素的效率取决于搜索过程的元素…

Spring-Interceptor拦截器

使用步骤 申明拦截器bean&#xff0c;并实现HandlerInterceptor接口 true为放行&#xff0c;false为拦截 2.定义配置类&#xff0c;继承WebMvcConfigurationSupport&#xff0c;实现addInterceptors方法&#xff0c;该方法调用具体的拦截器进行拦截 也可以在配子类通过实现W…

【Elasticsearch】DSL查询文档

目录 1.DSL查询文档 1.1.DSL查询分类 1.2.全文检索查询 1.2.1.使用场景 1.2.2.基本语法 1.2.3.示例 1.2.4.总结 1.3.精准查询 1.3.1.term查询 1.3.2.range查询 1.3.3.总结 1.4.地理坐标查询 1.4.1.矩形范围查询 1.4.2.附近查询 1.5.复合查询 1.5.1.相关性算分 …

Set与Map的使用 + 二叉搜索树与哈希桶的大白话讲解和图解+完整代码实现(详细注释)

文章目录 前言一、Set与Map概念及场景模型纯Key模型Key-Value模型 Map 的使用Set 的使用 二、二叉搜索树什么是二叉搜索树代码实现二叉搜索树查找操作插入操作删除操作(难点)cur这个节点没有左子树(cur.left null)cur这个节点没有右子树(cur.right null)cur这个节点没有左右子…

PyTorch深度学习实战(5)——计算机视觉

PyTorch深度学习实战&#xff08;5&#xff09;——计算机视觉 0. 前言1. 图像表示2. 将图像转换为结构化数组2.1 灰度图像表示2.2 彩色图像表示 3 利用神经网络进行图像分析的优势小结系列链接 0. 前言 计算机视觉是指通过计算机系统对图像和视频进行处理和分析&#xff0c;利…

【Python】正则表达式语法入门

目录 正则表达式 1、点&#xff1a;匹配所有字符 2、星号&#xff1a;重复匹配任意次 3、加号&#xff1a;重复匹配多次 4、花括号&#xff1a;匹配指定次数 5、贪婪模式和非贪婪模式 6、反斜杠&#xff1a;对元字符的转义 7、方括号&#xff1a;匹配几个字符之一 8、…

异地使用PLSQL远程连接访问Oracle数据库【内网穿透】

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 转载自cpolar极点云文章&#xff1a;公网远程连接…

cjson的内存泄漏案例

1、当我们使用下面这些创建json对象时&#xff0c;需要用cJSON_Delete();释放&#xff0c;&#xff08;当然&#xff0c;释放父JSON对象后&#xff0c;子JSON对象也会被释放&#xff09; 2、多次释放同一内存空间 在recv_write_property函数中的data&#xff0c;在Equipment_re…

Html基础知识学习——兼容问题与解决方法(十六)

文章目录 1.计算一定要精确&#xff0c;不要让内容的宽高超出我们设置的宽高&#xff0c;在IE6下内容会撑开设置好的宽高2.元素浮动&#xff0c;宽度需要内容撑开&#xff0c;就给里面的块元素都加浮动3.在ie6.ie7下元素要浮动并在同一行 就给这些元素都加浮动4.注意标签嵌套规…

【玩转Linux操作】Linux进程(进程基本介绍,父子进程,终止进程,进程树)

&#x1f38a;专栏【玩转Linux操作】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【Counting Stars 】 欢迎并且感谢大家指出小吉的问题&#x1f970; 文章目录 &#x1f354;进程的基本介绍&#x1f354;显示系统执行的进程⭐…

微服务 云原生:K8S 核心组件

参考 Kubernetes 官方文档&#xff0c;简要概述 Kubernetes 中的核心组件用途及部分原理。 一个 K8S 集群&#xff0c;可以分为两个部分&#xff1a; 控制平面(Control Plane)。它是一套管理系统&#xff0c;专门来管理集群节点和服务&#xff0c;为集群做出全局决策&#xff…

使用 @Autowired 为什么会被 IDEA 警告,应该怎么修改最佳?

# 问题原因 关于这个问题&#xff0c;其实答案相对统一&#xff0c;实际上用大白话说起来也容易理解。 1.初始化问题 先看一下Java初始化类的顺序&#xff1a;父类的静态字段 > 父类静态代码块 > 子类静态字段 > 子类静态代码块 > 父类成员变量 > 父类构造代码块…

Linux系统使用(超详细)

目录 Linux操作系统简介 Linux和windows区别 Linux常见命令 Linux目录结构 Linux命令提示符 常用命令 ls cd pwd touch cat echo mkdir rm cp mv vim vim的基本使用 grep netstat Linux面试题 Linux操作系统简介 Linux操作系统是和windows操作系统是并列…

数组与指针

博客内容&#xff1a;数组与指针 文章目录 一、 数组&#xff1f;指针&#xff1f;1.区别与联系大小赋值存储位置 二、指针数组、数组指针&#xff1f;二维数组和二级指针&数组名与数组的区别总结 一、 数组&#xff1f;指针&#xff1f; 数组 相同类型数据的集合 指针 指…

使用SpringBoot+React搭建一个Excel报表平台

摘要&#xff1a;本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 Excel报表平台是一款功能强大、操作简单的系统平台&#xff0c;可以帮助用户上传…

【C++/嵌入式笔试面试八股】二、24.TCP三次握手四次挥手 | TCP可靠性

TCP三次握手四次挥手 64.TCP头部中有哪些信息?❤️ TCP数据报格式(左图) UDP数据报格式也放这(右图),不具体解释了。 结合三次握手四次挥手来看 端口: 区分应用层的不同应用进程 扩展:应用程序的端口号和应用程序所在主机的 IP 地址统称为 socket(套接字),IP:端口…

如何在 Windows 中免费合并 PDF 文件 [在线和离线]

PDF是一种广泛使用的文件格式&#xff0c;具有兼容性好、安全性高、易于打印、方便浏览等众多优点。在工作和学习过程中&#xff0c;经常需要将同一类型的PDF文件合并起来&#xff0c;以方便传输和查看&#xff0c;使得合并PDF文件成为一种重要的数据整合方法。 如果您想知道如…

1、Kubernetes 概述和架构

目录 一、基本介绍 二、kubernetes功能和架构 2.1、 概述 2.2 、功能 &#xff08;1&#xff09;自动装箱 &#xff08;2&#xff09;自我修复(自愈能力) &#xff08;3&#xff09;水平扩展 &#xff08;4&#xff09;服务发现 &#xff08;5&#xff09;滚动更新 &a…

Linux进程理解【环境变量】

Linux进程理解【环境变量】 提到环境变量&#xff0c;大家可能有些陌生&#xff0c;如果编写过Java就知道&#xff0c;编写Java需要提前安装JDK&#xff0c;这个操作就是配置Java的编码环境&#xff0c;在Linux中当然也少不了环境变量&#xff0c;下面我们就一起来看看 文章目…