数据结构笔记(二)

在上次分享中,我分享了数据结构的一些基本概念,大家都知道,数据结构和算法是密不可分的,本次我将讨论算法的基本概念,以及时间复杂度等问题

什么是算法
算法是针对问题根据问题的特性来预先设计的求解过程。数据得以描述,目的是为了解决问题。如何针对各种各样的数据结构与问题规模去设计不同的过程解决特定的问题,这就是算法的艺术。鉴于在一个计算系统中计算资源的稀缺性,我们要设计不同的算法并且加以比较,从而选取最合适问题的算法方案去提升程序的经济性。
算法的五大特性
1、0个或多个输入  2、至少一个输出  3、有穷性  4、确定性  5、可行性
算法的设计的要求
1、健壮性  2、正确性  3、可读性  4、高效率  5、低存储
算法的优劣与算法描述的语言无关
好的算法和语言是没有任何关系的,在我认为,算法就是一种思想,好的算法可以是程序,也可以是一个公式,甚至可以是解决问题所画出来的图形。
如何衡量算法的好坏
一个算法的运行,会产生两种开销:
1)处理时间 (即时间复杂度)
2)空间或内存(即为空间复杂度)
上面我们引入了俩个很重要的概念,分别是时间复杂度和空间复杂度 <
  • 时间复杂度

计算机科学中,算法的时间复杂度是一个函数,它定性描述了该算法的运行时间。这是一个关于代表算法输入值的字符串的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是渐近的,它考察当输入值大小趋近无穷时的情况。

是不是觉得有点难以理解,还是直接上例子吧。

for(i=1;i<=n;i++)
    for(j=1;j<=i;j++)
        x=x+1;
//问时间复杂度为多少?
首先,我们看外层循环,i的值从1增到n,当i=1时,内层循环循环1次,当i=2,内层循环循环
了2次,如此,当i=n时,内层循环循环了n次,由此我们可以知道语句频度(即总共算了多少次)为
1+2+3+...+n=(n+1)n/2,当n->无穷大时,为n平方,则该算法的时间复杂度为O(n2)。

下面我们再看一个例子

s=0;
while (n>=(s+1)*(s+1))
	s=s+1;

看了之后是不是感觉太别扭了,浑身不舒服,别急,我们把条件那块化一下子。
我们可以将n>=(s+1)*(s+1)化成(s+1)<=n1/2,那么s<=n1/2-1,那么换成for循环,如下

for (s=0;s<=n^1/2-1;s++){
	s=s+1;
}

是不是看着舒服多了,来看怎么分析它的时间复杂度,那不就是当n=无穷的时候,循环了根号n次嘛,所以时间复杂度为O(n1/2)
那么,看到这块,大家是不是觉得时间复杂度也没有那么难了,那递归的时间复杂度怎么算,这里举一个python求斐波那契数列的递归例子

def fib(n):
	return(fib(n-1)+fib(n-2) if n>2 else 1)

是不是又有些蒙了,这个我们可以画个树来做,fib(n)=fib(n-1)+fib(n-2),fib(n-1)=fib(n-3)+fib(n-2),……

是不是一目了然了,当n为无穷大时,时间复杂度为O(2n)

  • 空间复杂度

空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度

空间复杂度由于人们往往体会不到,所以人们常常宁愿牺牲空间复杂度来减小时间复杂度,比如,用一个算法处理一个事件,程序运行时间为不到一秒,而另一个算法用了一个小时,你肯定就坐不住了吧。。但是占内存俩个算法你往往是体会不到的。这里也不做赘述了
通常来说,只要算法不涉及到动态分配的空间,以及递归、栈所需的空间,空间复杂度通常为0(1)
对于一个算法,其时间复杂度和空间复杂度往往是相互影响的。当追求一个较好的时间复杂度时,可能会使空间复杂度的性能变差,即可能导致占用较多的存储空间;反之,求一个较好的空间复杂度时,可能会使时间复杂度的性能变差,即可能导致占用较长的运行时间。另外,算法的所有性能之间都存在着或多或少的相互影响。因此,当设计一个算法(特别是大型算法)时,要综合考虑算法的各项性能,算法的使用频率,算法处理的数据量的大小,算法描述语言的特性,算法运行的机器系统环境等各方面因素,才能够设计出比较好的算法。
欢迎大家来看,来互相讨论呀,下一次我将分享线性表的定义与运算。

猜你喜欢

转载自blog.csdn.net/qq_42199781/article/details/86587139
今日推荐