目录
前言
这段时期学习数据结构,本篇是总结学习到的数据结构的知识点。
数据结构
解决问题方法的效率,跟数据的组织方式有关,跟空间的利用效率有关,跟算法的巧妙程度有关。
数据对象在计算机中的组织方式有两种:逻辑结构,物理存储结构。数据对象必定与一系列加在其上的操作相关联,完成这些操作所用的方法就是算法。
描述数据结构有一个很好的方法,叫做抽象数据类型(Abstract Data Type)。
数据类型包含两个东西:数据对象集,
数据集合相关联的操作集。
抽象:描述数据类型的方法不依赖于具体实现。
对一个数据类型的描述,应该:与存放数据的机器无关;
与数据存储的物理结构无关;
与实现操作的算法和编程语言均无关。
总体来说,我们只描述数据对象集和相关操作集“是什么”,并不涉及“如何做到”的问题。
算法(Algorithm)
定义:
- 一个有限指令集
- 接受一些输入(有些情况下不需要输入)
- 产生输出
- 一定在有限步骤之后终止
- 每一条指令必须:有充分明确的目标,不可以有歧义;在计算机能处理的范围之内;描述应不依赖于任何一种计算机语言以及具体的实现手段。
好的算法
衡量标准有两个指标:
- 空间复杂度S(n)——根据算法写成的程序在执行时占用存储单元的长度。这个长度往往与输入数据的规模有关。空间复杂度过高的算法可能导致使用的内存超限,造成程序非正常中断。
- 时间复杂度T(n)——根据算法写成的程序在执行时耗费时间的长度。这个长度往往也与输入数据的规模有关。时间复杂度过高的低效算法可能导致我们在有生之年都等不到运行结果。
一般来说在分析算法的效率时,我们经常关注下面两种复杂度:
很显然:平均复杂度 小于等于 最坏情况复杂度。但我们在分析时比较喜欢分析最坏情况复杂度,因为平均复杂度不是很容易计算,所以我们最关心最坏情况复杂度。
复杂度的渐进表示法
当我们在分析一个算法复杂度的时候,我们真的很有必要一步一步的去数计算机把一个算法做了多少次吗?其实没有必要。
其实我们关心的是随着要处理数据规模的增大,它的复杂度增长的性质会怎么样?
所以我们从来不对算法做十分精确的分析,只粗略的知道它的增长趋势就可以了,于是就有了复杂度的渐进表示法。
简单来说,O(f(n))表示f(n)是T(n)的某种上界,对于充分大的n而言。
类似地,如果看到第二种形式,表明g(n)是T(n)的某种下界;如果看到第三种形式,表示h(n)既是T(n)的上界又是下界,它们基本上是等价的。
注意:一个函数的上界和下界不是唯一的,它可以有无穷多个。
但是太大的上界和太小的下界对于我们分析一个算法的效率而言是没有什么帮助的。我们分析一个算法效率的时候总归希望不管是上界还是下界,都尽可能的与它的真实情况贴地越近越好。所以我们在写上界和下界时,写我们能力范围内能找到的最小的上界和最大的下界。
复杂度分析小窍门