第一个内容什么是算法?
什么是算法的复杂度?
什么是算法的空间复杂度?
我们的标题是数据结构和算法入门,这两个就是数据结构的入门,这三个就是算法的入门
什么叫算法?
算法就是指令的集合,是为解决特定问题而规定的一系列操作,我一般不愿意说概念性的问题,什么叫算法呢,简单的说,算法就是计算机解题
的思路,解题的过程,我们举生活中的一个例子来说,如何求1+2+3+....+100=?,我们怎么来实现,要实现的方式有很多
算法1: 我们学了 while do-while for循环,任何一种循环都可以吧这个问题搞定,因为1+2+3是可以重复的,用我们的循环语句,就可以
把这个问题搞定,但是大家要明白一点,我们使用计算机语言,是在欺负计算机,欺负他运算的快,充分的利用计算机运算的快
这个特征来做的,这个依次相加用for循环来算效率高吗?效率不高,但是就是计算机运行的速度比较快,那我们为什么还要用
循环,两个原因,第一个原因计算机运行的速度快,第二个对我们来说最主要的,我们写的代码少,我们写个for循环,两行代码
就出来了,是这么来做的,但是如果真的花的时间来说,这种效率还是比较低的,那有更好的办法吗,当然有了
算法2: 高斯解法,这个故事大家应该都知道,老师惩罚一个学生的,上课不好好学习,给你们出一道题,1+2+3+...+100=?,结果所有的学生
除了高斯都在蒙头拿着纸算,就像计算机一样,重复的操作,就高斯在那里不算,老师说你怎么不算,老师我已经算出来,不可能啊,
怎么回事,他就用梯形的面积公式来算,梯形的面积公式怎么来的,上底加下底,(1+100),一共有一百个数,(1+100)*100/2,
你看结果就出来了,如果是要加到10000,你换一下就可以了,(1+10000)*10000/2,他算3次,是不是就可以了,他也可以用
三角形的面积公式来算,如果三角形的面积公式来算前面要加个0,0+1+2+3+....+100=?,结果没有影响,底乘以高,底是多少
底是100,用了101个数,再除以2,100*101/2,有人说我不明白,这怎么可以用梯形面积来算呢,这个就不解释,明白就明白,
不明白我也就不在这里解释了,小学数据老师要解释的,如果要是10000的话,你采用两种方式的效率千差万别,效率差的
太多了,你的思维要扩散一下,不要总想着那三种循环,或者使用哪种循环,哪种循环都不对,必须要跳出这种循环的思维,
可以用这种方式来做,还有没有别的算法,他发的时间一样吗,不一样
算法3; 比如我们使用递归来实现,为什么呢,sum(100)=sum(99)+100,我想求出sum(100),我只要求出sum(99)就可以,但是你要想
求出sum(99),你只要求出sum(98)就可以了,依次往下类推,sum(2)=sum(1)+1,你想求出sum(2),你只要求出sum(1)就可以了
sum(1)=1,sum(1)就不用再求了,sum(1)就等于1,那你求sum(100),求sum(99),求sum(2)用的这种解题的思路都是
一样的,用递归,用递归来解决,这就是算法
一个问题,我们在这里提供了三种算法,请问我要用哪一个,我们怎么来评价算法的优劣,两个角度来考虑,第一个你要花多少时间,我要这个
时间短的,第二个你在内存里面占多少空间,我们要找那个占用内存空间少的,时间最少空间也最少的,有是最好,一般是没有的,有时候是
时间少了,空间可能就会多一些,空间少了时间可能就会多一些,一般来说是这样的,上面的例子来说那就是高斯解法,这个最简单了,时间
也少空间也少,我们下面会专门来分析的
什么叫算法?
我们给大家讲一下相关的理论大家知道,一个算法通常具有5个特征:
1. 输入:你得有输入,比如这个算法是输入100还是1万,就是上限,如果你都是从1开始的话,1就不用输了
2. 输出:输出什么意思,输出就是最终的结果
3. 可行性:我这个算法能算出来,5年之后这个算法就出来了,5年后黄花菜都凉了,生生再长长,长长再生生,那肯定不行,需要在有限的时间
内完成,对时间是有要求的
4. 有穷性:别来个死循环就行
5. 确定性:我同样的一个问题,算法每次解决的结果都一样
这就是我们讲的一些算法,再来看算法时间的复杂度.
大家想一下,算法的时间复杂度用英文来表示,Time Complexity两个单词,他的名词叫时间复杂度,它是没说时间,时间和时间复杂度
一样吗至少一说时间是什么啊,花了几秒,几微秒,那时间复杂呢,那就不是几秒和几微秒了,因为一个算法到底花几秒和几微秒,
这个你确定吗,你是不确定的,为什么不确定,具体花多长时间随着硬件的发展那个时间是没有多大现实意义的,但是我同样一个
算法不管在什么样的计算机上有一点是一样的,同样的一个算法写了一个程序,我在不同的电脑上花的时间是不一样的,但是有一点
是一样的,执行语句的条数是一样的,这一条算法都是这么多条语句呗,我把它都执行了一遍,为什么有些快有些慢,因为CPU的频率
不一样,有快有慢,所以大家记住.
时间频度: 对于一个算法来说,我们获取时间没有实际的意义,我们不可能对每个算法都上机测试,算算他一共花了几秒钟,因为这是
没有实际意义的,但是我们知道,一个算法花费的时间与算法中语句的执行次数是成正比的,语句越多时间越多,语句越少花的时间
就越少,所以我们就不算时间了,我们算一个算法中的语句的执行次数,一共执行多少次,这就叫执行次数,这叫时间复杂度吗,
不叫,他叫时间频度,用一个符号来 表示T(n),T是什么意思,T是Time,n就是问题的规模,你要运行个for循环,
for循环最后那个数是多少,n代表问题的规模,但是你会发现呢,这个时间频度,他不是时间复杂度,实际的过程中
我们也很少去计算时间的频度,比如说我们算了一下,比如一个算法我们费了九牛二虎之力T(N)是不是代表
时间频度啊,T(n)=100000n²+10n+6T(n)+6,这是一个时间频度,再来一个,T(n)=10n²+10n+6T(n)+6,后面又算了
一个T(n)=n²,比如我们一共有三个算法,语句执行次数,结果你发现他们的最高次幂,是不是都是一样的,最高次幂
都是一样的,当我们衡量一个算法的时间频度的时候,时间性能的话,我们会把这个问题再简化一下,怎么简化,
叫时间复杂度
时间复杂度: 我们想知道的是时间的规模,而不是具体的次数,想知道时间的规模,而不是具体的次数,所以我们引入了时间的复杂度,什么是
时间的复杂度T(n)=100000n²+10n+6,T(n)=10n²+10n+6,T(n)=n²,这叫不叫时间的复杂度,这叫时间频度,最高次幂
不是n的平方吗,低于n的平方的全部去掉常数项6去了,10n去了,最高的前面的系数10,也去了,常数低次幂也去了,
前面的这个系数很大,当n无穷大的时候系数100000还是一个常数,你还是一个特别小的数,大学学过数学应该
都知道这个问题了,我要把这个数也去了,上面是时间频度一共算了多少次,我们不研究这么细,我们只研究规模
就可以了,最后你发现T(n)=n²,T(n)都是n的平方了,但是我们能这么写吗,不能这么写,因为如果你这么写的话
就会理解成都和T(n)=n²一样,每个算法都是n的平方次,这个是具体的次数,这个只是规模,你怎么表示规模呢,
前面加上一个大O,这么来表示,Tn=O(n²)里面写n的平方,这么来写的话,他就不是时间频度了,就不是具体执行
的次数了,而只是问题的规模,我们研究到这个层次啊,就可以了,没有必要了,因为最高的次幂,就决定了
他的基本数量级了
一定要知道时间复杂度,我们把这个讲完之后总结一下,第一个回答我的问题
什么叫时间复杂度?
不是一个算法真正执行的时间,不是几秒几毫秒,不是一个算法真正执行的次数,真正执行的次数叫时间频度,那时间复杂度是什么?
是这个问题执行的规模,这个规模和时间频度是什么关系,去掉常数项,去掉低次幂,去掉最高次幂的常数,是不是用大O来表示,
这个大家明确了,时间复杂度
最坏时间复杂度和平均时间复杂度
你们想一下我们在实际的学习中,要计算一个算法的复杂度,我们是求他最快的呢还是求他平均的呢,一般来说我们是求平均的,在这里
告诉大家我们一般是求最坏时间复杂度,为什么呢?
1. 第一个平均时间复杂度,太难求了,要花很多的时间来求这个,
2. 还有一个你花半天劲把我求出来了,你会发现他跟最坏时间复杂度是一个级别的了,可能最坏时间复杂度后面有一个后缀,或者前面有个
系数,但是两个是一个级别的,我们本来就不求次数,我们要的是一个规模,所以基于这两点,我们一般讨论最坏时间复杂度就可以了
在这里我们认识三个符号,以后我们讨论时间复杂度,最多的是这个O,一般你把它叫做大哦就可以了,一见到大哦,我们就要明白,明白他是
最坏时间复杂度,T(n)=n²他是时间复杂度的上界,他是最坏情况,有时候你会见到T(n)=Ω(n²),他叫Omega,所以我用汉子标记一下
欧米伽Omega是最好的情况,他是最好的时间复杂度,那还有一个,如果最好和最坏是同一个级别的,那我么就用这个符号θ西塔,
如果你最好和最坏都是同一个级别的,T(n)=θ(n²),那我们就可以用这个符号来表示,这三个符号大家要知道,以后我们使用
最多的还是Tn=O(n²)这个,叫大哦表示法,这是我们讲的一些相关的概念。