《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两个判断。所以当数组大到一定程度的时候,第三个方案效率大于上面两个方案。

递归

递归是指在函数中对函数自身进行调用。

递归有两个特性:

  1. 必须有一个或对个基础情况,它是指不用递归而直接计算出结果。比如下面例子中:当 n=0 时,基础情况发生,f(0) = 1;
  2. 程序中的每个递归调用一定是通过一系列关于同一个问题的子问题的求解而最终迭代到基础情况。

下面是一个经典的递归例子,计算阶乘。

当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——循环和递归的更多相关文章

  1. <算法图解>读书笔记:第3章 递归

    第3章 递归 3.1 递归 程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一 ...

  2. Java 读书笔记 (十) 循环

    while循环 只要布尔表达式为true,循环就一直执行下去. public class Test( public static void main(String args[]){ int x=10; ...

  3. 《C++ Primer Plus》读书笔记之三—循环与关系表达式

    第五章 循环与关系表达式 1.表达式是值或者值与操作符的结合,每个C++表达式都有值.表达式到语句的转换只要加一个分号就可以完成.但是,反过来,从语句中删除分号,并不一定能将它转化成表达式. 2.前缀 ...

  4. 《Algorithms Unlocked》读书笔记2——二分查找和排序算法

    <Algorithms Unlocked>是 <算法导论>的合著者之一 Thomas H. Cormen 写的一本算法基础,算是啃CLRS前的开胃菜和辅助教材.如果CLRS的厚 ...

  5. SQL 横转竖 、竖专横 (转载) 使用Dapper.Contrib 开发.net core程序,兼容多种数据库 C# 读取PDF多级书签 Json.net日期格式化设置 ASPNET 下载共享文件 ASPNET 文件批量下载 递归,循环,尾递归 利用IDisposable接口构建包含非托管资源对象 《.NET 进阶指南》读书笔记2------定义不可改变类型

    SQL 横转竖 .竖专横 (转载)   普通行列转换 问题:假设有张学生成绩表(tb)如下: 姓名 课程 分数 张三 语文 74 张三 数学 83 张三 物理 93 李四 语文 74 李四 数学 84 ...

  6. 《algorithms Unlocked》读书笔记3——计数排序

    <Algorithms Unlocked>是 <算法导论>的合著者之一 Thomas H. Cormen 写的一本算法基础,算是啃CLRS前的开胃菜和辅助教材.如果CLRS的厚 ...

  7. js读书笔记

    js读书笔记 基本类型的基本函数总结 1. Boolean() 数据类型 转换为true的值 转换为false的值 Boolean true false String 任何非空字符串 "&q ...

  8. Linux Shell脚本攻略 读书笔记

    Linux Shell脚本攻略 读书笔记 这是一本小书,总共253页,但内容却很丰富,书中的示例小巧而实用,对我这样总是在shell门前徘徊的人来说真是如获至宝:最有价值的当属文本处理,对这块我单独整 ...

  9. React 读书笔记

    序言: 领导安排部门同事本月内看一本跟自己职业相关的书籍, 根基类的书籍已经看过了,重复阅读的意义不大,所以我平时看的都是视频,也许是视频作者没有出书的条件,也许是现在出书看的人越来越少了,也许有其他 ...

随机推荐

  1. Java源码ExtJS 5 SpringMVC 4Hibernate 4通用后台管理开发框架

    需要源码,请加QQ:858-048-581 一.特色1.采用Spring MVC的静态加载缓存功能,在首页将Javascript文件.CSS文件和图片等静态资源文件加载进来放进内存,极大提高ExtJS ...

  2. CSS 3 过渡效果之jquery 的fadeIn ,fadeOut

    .div { visibility: hidden; opacity: 0; transition: visibility 0s linear 0.5s,opacity 0.5s linear; } ...

  3. 每天一个linux命令(55)--at命令

    在Windows系统中,Windows提供了计划任务这一功能,在控制面板  ->  性能与维护  ->  任务计划,它的功能就是安排自动运行的任务.通过 ‘ 添加任务计划’ 的一步步引导, ...

  4. Laravel控制器和视图

    控制器,rawSQL,Model controller.php <?php namespace App\Http\Controllers; use Illuminate\Http\Request ...

  5. Kindle电子阅读器收不到个人文档推送解决方案

    最近我的 kindle 固件版本更新到 5.8.7.0.1 ,发现增加了生字注音功能,瞬间变成小学生阅读神器有木有,不过,这个功能可以隐藏.显示,看着碍眼隐藏即可,还可以减少和增加生字注音.感觉对于经 ...

  6. 《C#语言和数据库技术基础》单词必备

    <C#语言和数据库技术基础> 第一章1..NET Framework   框架2.sharp            尖锐,强烈的3.application      应用程序4.devel ...

  7. 使用grunt实现web自动化

    1.grunt作用        实现压缩.编译.单元测试等重复性工作 2.需要安装的软件          第一步:从官网获取nodejs的软件包,直接双击进行安装(windows下) 第二步:打开 ...

  8. 关于Dapper.NET的相关论述

    年少时,为何不为自己的梦想去拼搏一次呢?纵使头破血流,也不悔有那年少轻狂.感慨很多,最近事情也很多,博客也很少更新了,毕竟每个人都需要为自己的生活去努力. 最近在一个群里遇到一个人说的话,在这里不再赘 ...

  9. 【JS】JavaScript中的闭包

    在JavaScript中,闭包指的是有权访问另一个函数作用域中的变量的函数:创建闭包最常见的方式就是在一个函数内创建另一个函数.如下例子: function A(propertyName){ retu ...

  10. wemall app微信商城系统Android之通用通知接口demo

    wemall-mobile是基于WeMall的Android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享Native(原生)支付模式一demo,供技术 ...