这是数据结构
系列文章的第一篇,这是文章的列表。
注:想要学好数据结构,掌握至少一门语言是必需的,这样才能将学到的数据结构知识加以巩固。
文章目录
- 语言以及代码书写规范
- 时间复杂度和空间复杂度分析
- 数据结构与算法中的一些概念
1. 语言以及代码书写规范
- 语言其实无所谓,重点在于数据结构的知识。不同语言实现的数据结构算法,其实大同小异。在教科书中,常用的语言有
C/C++ 和 java
两种。
- 这两种语言在在数据结构与算法上,转化起来其实很简单,所以以后的文章,可能会用到这两种语言。
- 代码书写规范:
- 程序中用到的某些常量或者调用的函数等可以用加注释的方式,省略其定义。
- include语句可不写
- 测试代码可不写
- 数据类型上,int, char及其数组类型,指针类型即可覆盖大部分
2. 时间复杂度和空间复杂度分析
- 其实对于一些简单的程序,时间复杂度和空间复杂度是比较简单的,但是也有难的地方,特别是算法中涉及到递归等比较高级的特性时。时间复杂度的考察较多。
- 在考研中,时间复杂度的考察一般是考察排序算法中的复杂度,这只需要简单记忆或者理解记忆即可。当然,也不仅仅是这样的,也会给你一段程序,要你分析其复杂度,这就需要你有一定的分析能力了。
(1) 时间复杂度
1) 常用的时间复杂度比较关系(需要牢记):
2) 实例分析
- 分析时间复杂度其实就是分析算法每个指令执行的次数。而一般一行一行的代码其实其执行次数为常数,一般不考虑,所以一般要分析的地方在循环、递归等地方。
- 计算出执行次数后,一般是一个n的表达式,只需要提取式子中随着n的变化而变化最快的那个部分,一般是在(1)中比较关系里的那些。
实例1:纯循环的情况
这种情况只需要简单计算循环内的指令执行次数就行了。
以上代码第一层是n
次循环,第二层是n - (i + 1) + 1 = n - i
次循环,而i
是从0
开始到n - 1
, 所以总的次数应该是:
i = 0 时, target 运行 n - 1 次
i = 1 时, target 运行 n - 2 次
...
i = n - 1 时,target 运行 0 次
所以总共次数 = (n - 1) + (n - 2) + (n - 3) + ... + 0
总共有n项,根据等差数列求和:sum = ((n-1) + 0) * n/ 2 = n(n-1) / 2
实例2:循环次数依赖循环内数据变化的情况
有些题目中,循环的次数要依赖循环内部变量的变化情况而定。
上述代码只有一个while循环,但是循环次数需要通过i和s计算, 1,2两条指令会影响循环的跳出。并不是简单的自增1。
初始:i = 0, s = 0
i = 1, s += i = 1 // 1次
i = 2, s += i = 1 + 2 = 3 // 2次
i = 3, s += i = 1 + 2 + 3 = 6 // 3次
...
i = m, s += m = 1 + 2 + 3 + ... + m = m(m+1)/2 // m次
假设循环m次结束,那么 s = m(m+1)/2 >= n
换一种表示方式:m(m+1)/2 + k = n, k为一个常数
则有:m*m + m + 2k -2n = 0
按照前面所说取影响最大的一项做简化的规则,时间复杂度为:
实例3:递归的情况
递归的情况分析会比较难,但是也有一般的套路。上面的代码是归并排序的关键代码。merge函数的复杂度为
O(n)
。
-> 设因为merge的复杂度为O(n),所以可以假设其操作次数为cn,再假设mergesort的操作次数为f(n).
-> 实例中的规模为:j - i + 1,若调用mergesort(1, n), 那么规模就是n。
-> 一个规模为n的mergesort指令 = 两个规模为n/2的mergesort指令 + cn
即:
假设最后的问题