随笔

记录,分享,然后享受生活。

0%

数据结构与算法分析——C语言描述(第二版) 笔记

第1章 引论

用了两个例子(排序检索与字谜问题)来说明算法在处理问题中的重要性,一些算法在处理巨大数据集时所需要的时间是非常大的,这时候就需要更快更好的算法。接下来复习了数学方面指数、对数、级数相关的知识,这些在后面估计算法效率的时候会用到,也涉及了同余定理和两种证明方法(归纳和反证)。最后以递归的简介结束本章内容,在递归里面有一个自问自答比较有意思,是这样说的

一个常见的问题是:它(递归)是否就是循环逻辑?

答:虽然我们定义一个函数用的是这个函数本身,但是我们并没有用函数本身定义该函数的一个特定的实例。换句话说,通过使用F(5)来得到F(5)的值才是循环的,通过F(4)得到F(5)的值不是循环的,除非F(4)的求值又要用到对F(5)的求值。

笔者查阅了英文原版书后,感觉这里可能有个小小的误译

A common question is: Isn’t this just circular logic?

The answer is that although we are defining a function in terms of itself, we are not defining a particular
instance of the function in terms of itself. In other words, evaluating f(5) by computing f(5) would be circular.
Evaluating f(5) by computing f(4) is not circular—unless, of course f(4) is evaluated by eventually computing f(5).

这里的函数的实例就是具体使用函数时的调用,笔者猜测作者想要表达的意思可能是通过函数实例去定义抽象函数本身与通过函数实例去定义函数实例本身是不一样的,因为函数实例定义函数实例本身就如作者在书中所举的例子,用F(5)定义F(5),这样便产生了一个循环定义。而使用函数实例来定义抽象函数可以这样来理解,当调用抽象函数的时候也就是将抽象函数实例化的时候,这时的抽象函数实例与定义抽象函数实例中的函数实例不是同一个函数实例。这里可能说的有点绕,如果不清楚可以去看一下书上对于递归思想的描述,欢迎大家提出新的见解。

关于书写递归函数的四条基本法则:

1.基准情形

2.不断推进

3.设计法则

4.合成效益法则

练习

在1.3题中有说到精确度的问题,比如说理论上 $sin(\pi) = 0$ 但实际上 $\pi = 3.1415926…$ 这个无限不循环小数并不能被计算机完全表示,所以使用计算机计算 $sin(\pi)$ 是存在一定误差的。因此指定输出数字中的小数位数并进行四舍五入也就成了一种通俗的规定。

参考链接

《数据结构与算法分析:C语言描述》读书笔记