《Algorithms Unlocked》读书笔记1——循环和递归
《Algorithms Unlocked》是 《算法导论》的合著者之一 Thomas H. Cormen 写的一本算法基础。
书中没有涉及编程语言,直接用文字描述算法,我用 JavaScript 对书中的算法进行描述。
循环和查找
首先是三个简单的查找。目的是从数组中查找一个特定的值。
array: 一个数组
x: 要查找的值
// 简单的线性查找
function linearSearch(array, x) {
let answer = 'NOT-FOUND';
for (let i = 0; i < array.length; i++) {
if (array[i] === x) {
// 虽然找到了i, 但没有返回继续查找,直到 for 结束
answer = i;
}
}
console.log(answer);
return;
}
虽然找到了目标值,但for循环依然继续遍历直到结束,下面是优化
// 优化的查找,找到目标后立刻返回
function betterLinearSearch(array, x) {
for (let i = 0; i < array.length; i++) {
if (array[i] === x) {
// 直接返回
console.log(i);
return;
}
}
console.log('NOT-FOUND');
return;
}
还有一个问题是:假如直到最后都没有找到目标值,将试图访问越过数组末尾的元素。书上说:“在计算机程序中,当你试图访问越过数组末尾的元素时,结果通常是糟糕的。你的程序可能会崩溃,也可能会损坏数据。”
宁可信其有,不可信其无啊。继续优化。
// 更优的写法
// 总是让 for 循环可以结束
function sentinelLinearSearch(array, x) {
let n = array.length - 1; // 最后一个元素
// 把数组最后一个值保存到last变量中
let last = array[n]
// 把数组最后一个值替换成目标值
array[n] = x;
// 判断数组中是否有目标值x,即使没有,数组的最后一个值也一定是目标值,避免越过数组末尾的访问
let i = 0;
while (array[i] !== x) {
i++;
}
//如果i小于数组长度,或者最后一个值为目标值x,则返回i
array[n] = last;
if (i < n || last === x) {
console.log(i);
return;
}
return 'NOT-FOUND';
}
第三个方案在进行循环遍历的时候只进行了一个判断——array[i]是否等于x,而上面的两种方案在进行for循环时都要进行i是否大于length的判断和array[i]是否等于x两个判断。所以当数组大到一定程度的时候,第三个方案效率大于上面两个方案。
递归
递归是指在函数中对函数自身进行调用。
递归有两个特性:
- 必须有一个或对个基础情况,它是指不用递归而直接计算出结果。比如下面例子中:当 n=0 时,基础情况发生,f(0) = 1;
- 程序中的每个递归调用一定是通过一系列关于同一个问题的子问题的求解而最终迭代到基础情况。
下面是一个经典的递归例子,计算阶乘。
当n=0时,n! = 1 且 n! = n(n-1)(n-2)...3•2•1 (n≥0)
比如:5! = 5•4•3•2•1 = 120
// 阶乘
function factorial(n) {
if (n >= 0) {
if (n === 0) {
return 1;
};
return n * factorial(n - 1);
};
}
之前的查找算法也可以写成递归风格
// 线性查找的递归风格
function recursiveLinearSearch(array, i, x) {
if (i < array.length) {
if (array[i] === x) {
console.log(i);
return;
}else {
return recursiveLinearSearch(array, i+1, x);
}
}
console.log('NOT-FOUND');
return;
}
《Algorithms Unlocked》读书笔记1——循环和递归的更多相关文章
- <算法图解>读书笔记:第3章 递归
第3章 递归 3.1 递归 程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一 ...
- Java 读书笔记 (十) 循环
while循环 只要布尔表达式为true,循环就一直执行下去. public class Test( public static void main(String args[]){ int x=10; ...
- 《C++ Primer Plus》读书笔记之三—循环与关系表达式
第五章 循环与关系表达式 1.表达式是值或者值与操作符的结合,每个C++表达式都有值.表达式到语句的转换只要加一个分号就可以完成.但是,反过来,从语句中删除分号,并不一定能将它转化成表达式. 2.前缀 ...
- 《Algorithms Unlocked》读书笔记2——二分查找和排序算法
<Algorithms Unlocked>是 <算法导论>的合著者之一 Thomas H. Cormen 写的一本算法基础,算是啃CLRS前的开胃菜和辅助教材.如果CLRS的厚 ...
- SQL 横转竖 、竖专横 (转载) 使用Dapper.Contrib 开发.net core程序,兼容多种数据库 C# 读取PDF多级书签 Json.net日期格式化设置 ASPNET 下载共享文件 ASPNET 文件批量下载 递归,循环,尾递归 利用IDisposable接口构建包含非托管资源对象 《.NET 进阶指南》读书笔记2------定义不可改变类型
SQL 横转竖 .竖专横 (转载) 普通行列转换 问题:假设有张学生成绩表(tb)如下: 姓名 课程 分数 张三 语文 74 张三 数学 83 张三 物理 93 李四 语文 74 李四 数学 84 ...
- 《algorithms Unlocked》读书笔记3——计数排序
<Algorithms Unlocked>是 <算法导论>的合著者之一 Thomas H. Cormen 写的一本算法基础,算是啃CLRS前的开胃菜和辅助教材.如果CLRS的厚 ...
- js读书笔记
js读书笔记 基本类型的基本函数总结 1. Boolean() 数据类型 转换为true的值 转换为false的值 Boolean true false String 任何非空字符串 "&q ...
- Linux Shell脚本攻略 读书笔记
Linux Shell脚本攻略 读书笔记 这是一本小书,总共253页,但内容却很丰富,书中的示例小巧而实用,对我这样总是在shell门前徘徊的人来说真是如获至宝:最有价值的当属文本处理,对这块我单独整 ...
- React 读书笔记
序言: 领导安排部门同事本月内看一本跟自己职业相关的书籍, 根基类的书籍已经看过了,重复阅读的意义不大,所以我平时看的都是视频,也许是视频作者没有出书的条件,也许是现在出书看的人越来越少了,也许有其他 ...
随机推荐
- JS完成页面跳转并传参的方法|附加:循环遍历对象
此方法只能传递较少参数 方法如下: <a href='page/index.html'>跳转</a> 以上是正常写法,如果要传参按一下写法: <!--参数写在?后面,多个 ...
- [前言] 实现一个Android电子书阅读APP
大家好,我是小方,我将在接下来的几篇文章中从零实现一个网络小说阅读器,从安卓编程最基础的部分讲起,直至成功完成我们的应用,从新建一个项目开始,不断添加新的代码,添加新的界面,循序渐进,涵盖所有我们需要 ...
- C# 输入法
C# 输入法 虽说输入法不是什么新事物,各种语言版本都有,不过在C#不常见:这就会给人一种误会:C#不能做!其实C#能不能做呢,答案是肯定的--三种方式都行:IMM.TSF以及外挂式.IMM这种就是调 ...
- 香港多IP站群服务器-搭建多IP代理服务器、游戏加速服务器
耀磊花楹qq82521463香港WK自营机房多IP服务器租用,多IP站群服务器,多IP多C段 站群服务器租用 耀磊数据拥有3万个自由香港IP以及独立AS号,是APNIC核心成员,机房通过BGP融合 多 ...
- 1593: [Usaco2008 Feb]Hotel 旅馆
1593: [Usaco2008 Feb]Hotel 旅馆 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 391 Solved: 228[Submit ...
- 1088: [SCOI2005]扫雷Mine
1088: [SCOI2005]扫雷Mine Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1635 Solved: 979[Submit][Sta ...
- SDWebImage下载图片的使用
第一步,下载SDWebImage,导入工程.github托管地址https://github.com/rs/SDWebImage 第二步,在需要的地方导入头文件 1 #import "UII ...
- 用Jquery做一个时间日期选择器
今天我们就用Jquery做一个时间日期选择器,当打开网页时,文本框里面显示的是当前的日期,点击文本框可以出现年.月.日的下拉菜单,并且可以选择,会根据年份的选择判断是否是闰年,从而改变二月的天数,闰年 ...
- PHP语言开发微信公众平台(订阅号)之开启基本功能及获得可用的服务器地址(2)
1.开启群发功能(单击功能菜单里的"群发功能",并在右侧页面中点击"同意以上声明") 2.(1)在开启开发者模式之前需要完善个人资料(完成头像上传即可) (2) ...
- 去除IOS浏览器下面的工具栏
在head标签里添加下面的元素 即可 <meta id="viewport" name="viewport" content="width=de ...