数据结构
博主介绍:
– 本人是一个不知名的二本院校计科专业大二学生,每天除了上课就是在学校里的一个小组学习,之前学习了JAVA后学了Python如今在专注于学习Golang语言,每天总是很多胡思乱想,想一些不着调的想法,想做很多很多的软件让很多朋友们使用,但如今的技术还不到家,希望可以做出很多很多的APP给大家一起用,现仍需继续努力!一起加油!
有穷性:一个算法必须在有限的步数后结束并且在有限的时间内完成。
确定性:对于每种情况下所执行的操作,在算法中都有确切的规定,不会产生二义性,使算法的执行者或阅读者都能明确其含义及如何执行。
可行性:算法中的所有操作都可以通过已经实现的基本操作运算执行有限次来实现。
输入:一个算法可以有零个或多个输入。使用函数描述算法时,输入往往是通过形参表示的。一般都是从主函数进行调用传入输入值的。
输出:一个算法有一个或者多个输出,,都是算法进行加工后的结果,没有输出的算法没有任何意义。函数描述算法时,输出返回值或引用类型的形参表示。
一般从四个特性表示,分别是正确性、可读性、健壮性、高效性。
正确性:合理的数据输入下,可以在有限的运行时间内得到正确的结果。
可读性:首先就是便于人们理解和相互交流,其次才是机器的可执行性。可读性强的算法才便于人们更好的理解,而难懂的算法容易隐藏错误,后期的维护调试和修改也相对困难。
健壮性:当发生一些错误时,好的算法可以给出人性化的处理方式进行相应处理,而不会产生让大多数人理解不了莫名其妙的结果。
高效性:高效其中包括时间和空间两个方面。时间高效指算法设计合理,执行速度快,一般用时间复杂度来衡量;空间高效指算法占用存储空间容量合理,一般用空间复杂度来衡量。两个复杂度简称时空复杂度,也是衡量好坏算法的两个主要指标,具体使用还要场景适合时间高效还是空间高效亦或者取中。
衡量算法效率的方法一般有两种:
事后统计法:这种事后统计法需要先将算法实现,然后用程序进行测量事假和空间的开销。
事后统计法缺点:
一是必须把算法写出来进行执行
二是时空开销的结果全部依赖于计算机的软硬件等环节因素,容易掩盖算法实质性的优劣。
事前估算法:这种事前估算法,通过算法的渐进复杂度曲线来衡量算法的效率,采用事前用人工进行估算,不容易掩盖算法本身的优劣,通常采用事前估算法。
在不考虑计算机的软硬件外界环境的因素,影响算法时间 代价的主要原因是问题规模。问题规模就是算法求解问题输入量是多少,一般是问题数据量的大小的本质表示,一般用整数n表示。很显然n越大代表数据量越大,所以算法的执行时间也会很长。一个算法的执行时间大致上等于其所有语句的执行时间总和,而语句的执行时间则为该条语句的重复执行次数和执行一次所需时间的乘积。
语句频度:一条语句的重复执行次数。
一般情况一个算法的频度可以通过人工计算算出所有语句的执行次数,但是对于复杂的算法,计算起来还是比较困难的,也可能是非常复杂的函数和方法。
例如T(n)=O(f(n)) 它表示随问题的规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称做算法的渐进时间复杂度,简称时间复杂度。
O(1) 复杂度 一般代表常量增长的,一般指你的运行时间是知道的,是可以数的。
O(n) 复杂度 一般代表无限次的线性增长。
O(㏒2n) 复杂度 代表以2为低n的对数,一般比N的平方慢,比如二分查找
O(n2) 复杂度 是平方阶的增长曲线。
O(n3) 复杂度 是立方阶的增长曲线,以后的一次类推
O(2n): 复杂度 具有n个元素集合的所有子集的算法
O(!n): 复杂度 是n的阶乘增长曲线,目前为最高的增长曲线。
这里举例几个常用的
常量O(1) 列如:
for(int i = 0; i < 20; i++)
常量O(n) 列如:
for(int i = 0; i < n; i ++){
}
常量O(㏒2n) 列如:
for(int i = 0; i < n; i ++){
for(int j = 0; j <= i; j ++){
}
}
常量O(n2) 列如:
for(int i = 0; i < n; i ++){
for(int j = 0; j < n; j ++){
}
}
常量O(n3) 列如:
for(int i = 0; i < n; i ++){
for(int j = 0; j < n; j ++){
for(int k = 0; k < n; k ++){
}
}
}
最好时间复杂度:算法在最好情况下的时间复杂度为最好时间复杂度,指的是算法计算量可能达到的最小值;
最坏时间复杂度:算法在最坏情况下的时间复杂度为最坏时间复杂度,指的是算法计算量可能达到的最大值;
平均时间复杂度:算法的平均时间复杂度是指算法在所有可能情况下,按照输入案例以等概率出现时,算法计算量的加权平均值。
空间复杂度:算法的存储空间需求,类似于算法的时间复杂度,采用渐进的空间复杂度作为算法所需存储空间的量度,简称空间复杂度。
空间复杂度O(1)
for(int i = 0; i < n/2; i++){
t = a[i];
a[i]=a[n-i-1];
a[n-i-1] = t;
}
空间复杂度O(n)
for(int i = 0; i < n; i++)
b[i]=a[n-i-1];
for(int i = 0; i < n; i++)
a[i]=b[i];
时间复杂度和空间复杂度是互相影响的,因为没有一个算法是可以两个都很好,只能取一方或者取折中,一般采用等价代换的方式,大多算法都是空间复杂度很高,而时间复杂度很低,也是算法中常用的重要思维,以空间换时间。