第二章 算法(数据结构笔记)

xiaoxiao2021-02-28  87

1.算法比较

我自己写的累加算法(1-100)

int i,count=0; for(i=0;i<=100;i++) { count+=i; } cout<<count<<endl; return 0; }

高斯的累加算法

int n=100,count=0; count=(n*(n+1))/2; cout<<count;

这个算法是高斯在童年时期想出来的,聪明之处在于就算累加到一千,一万,也是可以瞬间得出的,但是用传统的累加算法就需要成千上万次的加法循环。

2.算法定义

算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。 算法定义中提到了指令,指令能被人或机器等计算装置执行。它可以是计算机指令,也可以是我们平时的语言文字。 为了解决某个或某类问题,需要把指令表示成一定的操作序列,操作序列包括一组操作,每一个操作都完成特定的功能,这就是算法了。

3.算法的特性

算法具有五个基本特性:输入,输出,有穷性,确定性和可行性。

1.输入和输出: 算法具有零个或多个输入,至少有一个或读个输出。

2.有穷性: 指算法在执行有限的步骤之后,自动结束而不会无限循环,并且 每一个步骤在可接受的时间内完成。 当然这里的有穷性并不是纯数学意义,而是在实际应用当中合理的,可以接受的“有边界”,如果一个算法的运行时间是二十年,从数学意义上讲自然是有穷的,但是算法的意义也就不大了。

3.确定性: 算法的每个步骤都有确定的意义,不会出现二义性。

4.可行性: 算法的每一步骤都必须是可行的,也就是说,每一步骤都能通过执行有限次完成。 可行性意味着算法可以转换成程序上机运行,并得到正确的结果。

4.算法设计的要求

综合来说,好的算法应该具有正确性,可读性,健壮性和低存储量的特征。 1.正确性:算法的正确性是指算法至少应具有输入,输出和无歧义性,能正确反映问题的需求,能够得到问题的正确答案。 但是算法的“正确”通常在用法上有很大区别,大体分为以下四个层次: a.算法程序没有语法错误。 b. 算法程序对于合法的输入数据能够产生满足要求的输出结果。 c.算法程序对于非法的输入数据能够得出满足规格要求的结果。(一般情况下以此作为好算法的判断标准) d.算法程序 对于精心选择的甚至刁难的测试数据都有满足要求的输出结果。(难验证)

还有,好的算法容易理解。

2.可读性:算法设计的另一目的是为了便于阅读,理解和交流。 可读性高的算法有利于理解和交流,晦涩难懂的算法往往隐含错误,不易被发现,并且难以调试和修改。

3.健壮性:当输入数据不合法时,算法也能做出相关处理,而不是产生异常或莫名其妙的效果。

4.时间效率高和存储量低:时间效率指算法的执行时间,对于同一个问题,执行时间短的算法效率高;存储量需求指的是算法在执行过程中需要的最大存储空间,主要指算法运行时所占用的内存或外部硬盘存储空间。好的算法应该尽量满足时间效率高和存储量低的需求。

5.算法效率的度量方法

利用计算机的计时功能来确定算法效率的高低。

a.事后统计方法:这种方法主要是通过设计好的测试程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。 这种方法的缺陷有: 1. 必须依据算法事先编制好程序,这需要大量的时间和精力,如果测得结是一个糟糕的算法,那就有些得不偿失了。 2. 时间的比较依赖计算机软件和硬件等环境因素,有时会掩盖算法本身的优劣。 3. 算法的设计数据设计困难,并且程序的运行时间往往还与测试数据的规模有很大关系,效率高的算法在小的测试数据面前往往得不到体现, 基于这些缺陷,不采纳此方法。 b.事前分析估算方法:在计算机程序编制前,依据统计方法对算法进行估算。 经过分析,我们发现,一个用高级程序编写的程序在计算机上运行时所消耗的时间取决于下列因素: 1.算法采用的策略、方法。 2.编译产生的代码质量。 3.问题的输入规模。 4.机器执行指令的速度。 第一条是算法好坏的根本,第二条要由软件来支持,第四条取决于硬件性能。除了计算机硬件,软件有关的因素,一个程序的运行时间,依赖于算法的好坏和问题的输入规模。

我们在分析一个算法的运行时间时,最重要的 是把基本操作的数量与输入规模关联起来,即基本操作的数量必须表示成输入规模的函数。

c.函数的渐进增长

输入规模 n 在没有限制的情况下,只要超过一个数值 n ,这个函数总是大于另一个函数,我们称函数是渐进增长的。

其中要注意的有: 1.可以忽略加法常数,如 2n+3,可以只按照 2n 来分析。 2.与最高次项相乘的常数不重要,最高次项指数大的,函数随着 n 的增长,结果也会变得增长特别快。

所以,判断一个算法的效率时,函数中的常数和其他次要项常常可以省略,而更应关注主项(最高阶项)的阶数。

判断算法优劣时,我们可以对比这几个算法的关键执行次数函数的渐进增长性,基本就可以分析出,某个算法,随着 n 的增大,它会越来越优于某个算法,或者越来越差域某个算法。这其实就是事前估算方法的理论依据,通过算法时间复杂度来估算算法时间效率。

d.算法时间复杂度

1.大O阶 在进行算法分析时,语句总的执行次数 T(n) 是关于问题规模 n 的函数,进而分析 T(n)随 n 的变化情况并确定 T(n) 的数量级。算法的时间复杂度,也就是算法的时间量度,记做: T(n) =O(f(n))。它表示随问题规模 n 的增大,算法执行时间的增长率和 f(n) 的增长率相同,称作算法的渐进时间复杂度,简称为时间复杂度。其中 f(n)是问题规模 n 的某个函数。 这样用大写 O 来体现算法复杂度的记法,我们称之为大O记法。 一般情况下,随 n 的增大,T(n) 增长最慢的算法称为最优算法。

2.推导大O阶的方法: a.用常数1取代运行时间中的所有加法常数。 b.在修改后的运行次数函数中,只保留最高阶项。 c.如果最高阶项存在且不是一,则去除与这个项相乘的常数。 d.如此得到的结果就是大O阶。

3.常数阶: 与问题的大小(n的多少)无关,执行时间恒定的算法,我们称之为具有O(1)的时间复杂度的算法,又叫常数阶。如: ` int n=100,count=0; count=(n*(n+1))/2; cout<

转载请注明原文地址: https://www.6miu.com/read-77538.html

最新回复(0)