数据结构---算法概述与复杂度分析

一、算法的概念

算法是解决特定问题的步骤描述,在计算机中表现为指令的有限序列,每条指令代表一个或多个操作。

二、算法的特性

有穷性;

确定性;

可行性;

输入与输出;

三、算法设计要求

正确性;

可读性;

健壮性;

高效性和低存储;

四、算法的复杂度分析(效率度量方法)

1、事后统计:

通过设计好的样本对程序的运行时间进行统计和比较,进而得出算法效率的高低。

该方法必须事先写好该算法的程序,并根据设计好的样本数据对程序运行时间进行统计,这往往会浪费大量的时间,并且不一定会得到效率较高的算法。

样本数据设计困难。算法的效率还受到计算机的硬件和数据规模大小等众多因素的影响。

此方法不适用。

2、事前分析:

将准备做在事前,不是没有道理的。在编程前,对该算法的效率进行估算,往往能排除很多不必要的问题,提高我们分析的效率。

经过前辈们的分析总结,高级程序语言编写的程序运行时间的因素有:

a、算法的方法和策略。

 b、编译器产生的代码质量,不过一般来说现代编译器都会进行相应的优化,产生的代码质量基本差不多。

c、问题输入的数据规模。

d、机器执行指令的速度。(与b类似,基本相同)

3、先来看一个例子:

高斯小时候的故事大家都听过,求1-100数的和。

高斯这种神人当然就是要自创公式了,也就是后来的等差数列的求和公式

sum=\sum_{i=1}^{100}i=n(n+1)/2;

sum=100*(1+100)/2;

//sum=5050

但如果我们在不知道这样的公式的情况下,可能想到的方法就是暴力求和了。

int sum=0;
for(int i=1;i<=100;i++)
sum+=i;
printf("%d",sum);

//sum=5050;

求和公式只执行依次就可以得出结果,但暴力循环的方法却执行了100次。

如果 n 很大的话,执行起来的时间就不是差一点了,这就是算法的精妙所在,它可以将复杂的、麻烦的问题在很短的时间内解决。

顺便提一下,1-n求和的复杂度分别为  O(1) 和 O(n)

我们将上面的例子加以扩展:

for(int i=1;i<=n;i++)// 执行 n+1 次;
{
    for(int j=1;j<=n;j++) //执行 n*(n+1)次;
    sum+=j;// 执行 n*n 次;
}

// 总的执行次数:2n^2+2n+1 次

这里出现的两层的 for 循环,并且我们可以算出总的执行次数为2n^2+2n+1 次。那么我们可以想一下,当 n 的值很大很大时,n^2成为了影响次数的最主要的因素,那么我们可以忽略剩下的,光看n^2,也就可以得出 该算法的时间复杂度为 O(n^2)。

这也就是所谓的函数渐近增长。判断一个算法的效率时,函数的常数和其他的次项可以忽略,关注最高次项的阶数

在分析程序运行时间时,最重要的是把程序看成独立于程序设计语言外的算法或者一系列步骤。

四、算法的时间复杂度分析

1、算法的时间复杂度:

在进行算法分析时,语句的执行次数Tn 是关于问题规模 n 的函数,算法的时间复杂度,也就是算法的时间量度,记作:

Tn= O( fn ),表示随 n 的增大,算法的执行时间增长率和 fn的增长率相同,称作算法的渐近时间复杂度。

2、推导 O(n) 的方法:

a、直接看。。。做多了就直接看出来了。。平常写程序就是看着估算。

b、像上面的例子一样,计算所有语句的执行次数,然后找最高项,其实叶不用算的太准确,差不多感觉就可以。

3、常见的时间复杂度:

a、常数阶 O(1):

sum=100*(1+100)/2;

//sum=5050

b、线性阶 O(n):

int sum=0;
for(int i=1;i<=100;i++)
sum+=i;
printf("%d",sum);

//sum=5050;

c、平方阶 O(n^2)

for(int i=1;i<=n;i++)// 执行 n+1 次;
{
    for(int j=1;j<=n;j++) //执行 n*(n+1)次;
    sum+=j;// 执行 n*n 次;
}

// 总的执行次数:2n^2+2n+1 次

d、还有常见的 对数阶(logn),nlogn阶(nlogn),立方阶(n^3),指数阶(2^n).

O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n)

3、最坏情况与平均情况

如果我们想在一串数字中去找数,恰巧第一个就是,那么这就是最好的情况。类似的,最坏的情况就是最后一个数字是我们要找的。

如果我们要将一串数字从小到大排序,如果这串数字是从大到小排的,此时就有点尴尬了,我们需要将整串数字颠倒,这也是最坏的情况。

最坏情况的运行时间是一种保证,是程序运行时间的上限,我们平常所说的运行时间一般就是最坏情况的运行时间。

平均时间是所有情况中最有意义的,它反映了算法在处理各种数据时的平均时间,最具代表性,但它需要运行多组数据来统计估算。

五、算法的空间复杂度

我们在处理各种刁钻问题时,为了减少程序运行时间,经常会用空间来换时间,牺牲一定的存储空间来提高程序的运行效率。

此时我们就用到了辅助空间,如果我们用到的辅助空间相对于n来说是个常数,即可忽略,那么我们称此算法为 原地工作(很形象),空间复杂度为 O(1).

 

 总结:算法,有着化腐朽为神奇的力量,总令我们感叹思维的伟大,总令我们去苦苦追寻,去探索发现,正是如此,我们的科技不断地进化和成长,推动着人类社会和历史的发展进步。

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值