《数据结构与算法分析--c语言描述》之第一章:引论

《数据结构与算法分析--c语言描述》之第一章:引论_第1张图片

学习《数据结构》与《算法设计与分析》这两门课程已经有一段时间了。但在设计编写代码时,还是不能做到游刃有余。怎么说呢?平时在编写代码的时候不会去考虑很多。诸如:是否要用哪个数据结构?是否可以用哪个算法?之类的问题很少会在脑海浮现。原因是:当想到用哪个数据结构或者哪个算法时,往往发现实现起来很麻烦,很难,总得花不少时间去重翻课本,对自己的要求就是写出能工作的程序就行了。久而久之也就对这样的想法敬而远之了。这样编程写的代码无法突破顺序,简单的模式,不仅如此,代码没有使用很好的算法,还有一个致命的缺点:效率低下。除非特意去花时间突破这些瓶颈。我所说的游刃有余是:编写代码时,无意识地,潜意识地使用高级数据结构,使用高效算法。无需去特意要求自己,对于自己,这样的编写代码不是一种要求,而是一种习惯。使用好的数据结构,使用好的算法就是理所当然的,就像吃饭,有谁不吃饭的呢?有谁编程不使用好的数据结构,好的算法呢?还有一个原因,长期以来的学习,我深深的意识到:数据结构与算法设计好比程序员的内功。掌握了内功心法,学什么东西都快,都跟容易。就好比张无忌练就乾坤大挪移内功心法,龙爪手片刻精通,就好比周星驰韦小宝得了神龙教内功,一跳冲天。

  基于以上原因,我买了《数据结构与算法分析--c语言描述》这本书,决定好好修炼我的内功。内功修炼,不比套路,需要很高的悟性,需要很有耐心,会让你很痛苦,会花掉你很多时间。当绝不能半途而废。

 

1.1 本书讨论的内容

生活中的问题可以用很多种算法来解决,小规模的问题上,看不出不同算法孰优孰劣。大规模的问题,好的算法体现的优势让你惊叹不已,坏的算法几天的计算才能得出的结果,用好的算法有时几秒中就可以出来,甚至时间更短。设计算法,掌握好的算法,辨别算法的好坏,就是接下来要学习的。

1.2 数学知识复习

指数

 指数1

指数2

指数3 

指数4

指数5

对数

对数1

对数2

对数3

对数4

对数5

对数7

级数

等比求和公式

级数1

模运算

模运算

模运算1

模运算2

证明方法:

归纳法:

第一步:证明基准情形,一般是显而易见的,可直接得出的。

第二步:进行归纳假设,假设定理对直到某个有限数k的所有的情况都是成立的。然后使用这个假设(必须),证明定理对于下一个值(通常为k+1)也是成立。也就证明了在k是有限的情况都成立。

反例法:

随便举出一个不符合的情况即可推翻定理。

反证法:

通过假设定理不成立,然后证明该假设导致某个已知的性质不成立,宠儿说明原假设是错误的。

1.3 递归简论

递归的四条基本法则:

(1)基准情形。(必须存在,无须递归就能解出)

(2)不断推进。(递归求解的方向:每次递归都朝着基准情形接近一步,知道最后到达基准情形得出结果)

(3)设计法则。(假设所有递归都能运行,设计递归程序时没有必要知道簿记的细节

(4)合成效益法则。(在求解一个问题的同一实例时,切勿在不同的递归调用中做重复性的工作(才能高效益),用动态规划可以满足结果的重用,不重计算)

// 递归打印正整数
void PrintOut(unsigned int N)
{
    if (N >= 10)
    {
        PrintOut(N/10);
    }
    printf("%d", N%10);
} 

练习

1.8 2^100(mod 5)是多少?

模运算2

2^1 (mod 5) = 2^5 (mod 5)

(2^1 * 2^4) (mod 5) = (2^5 * 2^4) (mod 5)

2^5(mod 5) = (2^1 * 2^4)(mod 5)

2^1(mod 5) = (2^5 * 2^4)(mod 5)

...

2^1(mod 5) = 2^5 (mod 5) = 2^9 (mod 5)...2^(1+4k) (mod 5) = 2

2^2(mod 5) = 2^6 (mod 5) = 2^10 (mod 5)...2^(2+4k) (mod 5) = 4

2^3(mod 5) = 2^7 (mod 5) = 2^11 (mod 5)...2^(3+4k) (mod 5) = 3

2^4(mod 5) = 2^8 (mod 5) = 2^12 (mod 5)...2^(4k) (mod 5) = 1

2^100(mod 5)= 1


你可能感兴趣的:(数据结构)