《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. 一个好用的几乎没有Callback的Android异步库

    android-async-task 这是一个Android平台处理复杂异步任务的库 (https://github.com/gplibs/android-async-task) 1. 安装方法 gr ...

  2. Java基础——运算符

    一.赋值运算符 在前面的学习中,用到最多的是什么呢?就是“=” .例如:int money=1000;   //储存本金 使用“=”将数值1000放入变量money的存储空间中.“=”称为赋值运算符. ...

  3. Caffe学习系列(二)Caffe代码结构梳理,及相关知识点归纳

    前言: 通过检索论文.书籍.博客,继续学习Caffe,千里之行始于足下,继续努力.将自己学到的一些东西记录下来,方便日后的整理. 正文: 1.代码结构梳理 在终端下运行如下命令,可以查看caffe代码 ...

  4. KoaHub.JS基于Node.js开发的处理和显示日期代码

    moment Parse, validate, manipulate, and display dates      A lightweight JavaScript date library for ...

  5. node.js爬虫爬取拉勾网职位信息

    简介 用node.js写了一个简单的小爬虫,用来爬取拉勾网上的招聘信息,共爬取了北京.上海.广州.深圳.杭州.西安.成都7个城市的数据,分别以前端.PHP.java.c++.python.Androi ...

  6. 3298: [USACO 2011Open]cow checkers

    3298: [USACO 2011Open]cow checkers Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 65  Solved: 26[Su ...

  7. 算法模板——sap网络最大流 1(非递归+邻接矩阵)

    实现功能:首行输入N,M,S,T,代表这张图N个点,M条边,源点为S,汇点为T:接下来T行输入个边的出发点.终点和权值:输出最大流 原理:sap网络流算法(详见百度百科,个人觉得这个模板已经不错了,虽 ...

  8. 1798: [Ahoi2009]Seq 维护序列seq

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 2930  Solved: 1087[Submit ...

  9. WCF请求数据:已超过传入消息(65536)的最大消息大小配额。若要增加配额,请使用相应绑定元素上的 MaxReceivedMessageSize 属性。

    通常情况下,写好WCF服务后都会用自带的WCFClient工具进行测试,在进行时数据请求的时候,如果返回数据量超过默认接收值的时候就会提示如图异常错误. 错误也提示的很清楚,无非就是修改接收值大小的问 ...

  10. pageRank算法 python实现

    一.什么是pagerank PageRank的Page可是认为是网页,表示网页排名,也可以认为是Larry Page(google 产品经理),因为他是这个算法的发明者之一,还是google CEO( ...