《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 读书笔记
序言: 领导安排部门同事本月内看一本跟自己职业相关的书籍, 根基类的书籍已经看过了,重复阅读的意义不大,所以我平时看的都是视频,也许是视频作者没有出书的条件,也许是现在出书看的人越来越少了,也许有其他 ...
随机推荐
- asp.net EF+MVC+Bootstrap 通用后台管理系统
需要源码,请加QQ:858-048-581 开发环境: VS2012或以上 数据库: SQL Server 2008R2或以上 基于EF+MVC+Bootstrap构建通用后台管理系统,集成轻量级 ...
- stm32 复位后 引起引脚的变化,输出电平引起的问题
在做项目的时候,需要通过蓝牙发送指令给STM32,使其复位,然后进入bootloader程序进行升级,但是复位后会导致蓝牙模块关机.stm32有个引脚连接着蓝牙的开关机引脚,高电平开机,低电平关机,我 ...
- C++ 11 学习2:空指针(nullptr) 和 基于范围的for循环(Range-based for loops)
3.空指针(nullptr) 早在 1972 年,C语言诞生的初期,常数0带有常数及空指针的双重身分. C 使用 preprocessor macroNULL 表示空指针, 让 NULL 及 0 分别 ...
- [干货来袭]C#7.0新特性(VS2017可用)
前言 微软昨天发布了新的VS 2017 ..随之而来的还有很多很多东西... .NET新版本 ASP.NET新版本...等等..太多..实在没消化.. 分享一下其实2016年12月就已经公布了的C#7 ...
- Python开发【第十八篇】Web框架之Django【基础篇】
一.简介 Python下有许多款不同的 Web 框架,Django 是重量级选手中最有代表性的一位,许多成功的网站和APP都基于 Django. Django 是一个开放源代码的Web应用框架,由 P ...
- Sersync实时同步
sersync会对目录进行监控,将变化的目录或文件同步到远程服务器.sersync是递归监控的,如果有多级目录 ,都会同步到远程服务器. sersync依赖于rsync进行同步,在同步主服务器上开启s ...
- C#与Java区别(一)
最近学了点java,总结了一些和c#的语法区别,欢迎大家指点和补充,如下: 1.java支持跨平台,当然.net core现在也支持. 2.java中用package,c#中用namespace定义空 ...
- 学学简单的-------------javaScript基础
首先知道什么是JavaScript? JavaScript是一种描述性语言,也是一种基于对象和事件驱动的.并具有安全性的脚本语言. 2.JavaScript由三部分组成:①ecmascript ②Bo ...
- web从入门开始(1)------简介
服务端与客户端 HTML简介
- Python中的日期和时间
感觉C语言作为一门编程的入门语言还是很好的,相比较之下,Python为代表的一些语言,适合很多非计算机专业的编程入门学习. Python 日期和时间 Python 程序能用很多方式处理日期和时间,转换 ...