-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
101 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
|
||
|
||
|
||
# 概述 | ||
|
||
|
||
> 数据结构是程序的骨架,而算法则是程序的灵魂。 | ||
|
||
《算法 + 数据结构 = 程序》 是 Pascal 语言之父 Niklaus Emil Wirth 写过的一本非常著名的书。而作为书名的这句话也成为了计算机科学的经典名句。可见,对于程序设计来说,算法和数据结构的关系密不可分。 | ||
|
||
大部分数据结构和算法教材,在开篇都试图会给这两个概念下一个明确的定义。但是,这些定义都很抽象,对理解这两个概念并没有实质性的帮助 | ||
|
||
|
||
从广义上讲,数据结构就是指一组数据的存储结构。算法就是操作数据的一组方法。 | ||
|
||
数据结构是计算机存储、组织数据的方式,是指相互之间存在一种或多种特定关系的数据元素的集合 | ||
|
||
|
||
数据结构和算法是相辅相成的。数据结构是为算法服务的,算法要作用在特定的数据结构之上。 因此,我们无法孤立数据结构来讲算法,也无法孤立算法来讲数据结构。 | ||
|
||
|
||
算法(Algorithm)是指用来操作数据、解决程序问题的一组方法。对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源和时间却会有很大的区别。 | ||
|
||
|
||
想要学习数据结构与算法,首先要掌握一个数据结构与算法中最重要的概念——复杂度分析。 | ||
|
||
《数据结构和算法》解决的是如何更省、更快地存储和处理数据的问题,因此,我们就需要一个考量效率和资源消耗的方法,这就是复杂度分析方法。 | ||
|
||
所以,如果你只掌握了数据结构和算法的特点、用法,但是没有学会复杂度分析,那就相当于只知道操作口诀,而没掌握心法。 | ||
|
||
那么我们应该如何去衡量不同算法之间的优劣呢?主要还是从算法所占用的「时间」和「空间」两个维度去考量。 | ||
|
||
- 时间维度:是指执行当前算法所消耗的时间,我们通常用「时间复杂度」来描述。 | ||
|
||
- 空间维度:是指执行当前算法需要占用多少内存空间,我们通常用「空间复杂度」来描述。 | ||
|
||
因此,评价一个算法的效率主要是看它的时间复杂度和空间复杂度情况。然而有时候,时间最优和空间最优往往是「鱼和熊掌」不可兼得,那么我们就需要从中去取一个平衡点。 | ||
|
||
|
||
|
||
同一个算法在不同的计算机上运行的速度会有一定的差别,并且实际运行速度难以在理论上进行计算,实际去测量又比较麻烦,所以我们通常考虑的不是算法运行的实际用时,而是算法运行所需要进行的基本操作的数量。 | ||
|
||
|
||
|
||
|
||
|
||
|
||
## 复杂度 | ||
|
||
|
||
```java | ||
int cal(int n) { | ||
int sum = 0; | ||
int i = 1; | ||
for (; i <= n; ++i) { | ||
sum = sum + i; | ||
} | ||
return sum; | ||
} | ||
``` | ||
|
||
|
||
在普通的计算机上,加减乘除、访问变量(基本数据类型的变量,下同)、给变量赋值等都可以看作基本操作。对基本操作的计数或是估测可以作为评判算法用时的指标。 | ||
|
||
从CPU的角度来看,这段代码的每一行都执行着类似的操作:读数据——运算——写数据。 | ||
|
||
尽管每行代码对应的CPU执行的个数、执行的时间都不一样,这里只是粗略估计,假设每行代码执行的时间都一样,为unit_time。 | ||
|
||
第2、3行代码分别需要1个unit_time的执行时间,第4、5行都运行了n遍,所以共需要 2n * unit_time 的执行时间,所以这段代码总的执行时间就是(2n+2) * unit_time | ||
|
||
可以看出来,所有代码的执行时间T(n)与每行代码的执行次数成正比。 | ||
|
||
``` | ||
T(n) = O(f(n)) | ||
``` | ||
|
||
T(n) 它表示代码执行的时间; n 表示数据规模的大小; | ||
f(n) 表示每行代码执行的次数总和。因为这是一个公式,所以用 f(n) 来表示。 | ||
|
||
公式中的 O ,表示代码的执行时间 T(n) 与 f(n) 表达式成正比。 | ||
|
||
|
||
第一个例子中的T(n) = O(2n+2),第二个例子中的T(n) = O(2n 2 +2n+3)。 | ||
|
||
|
||
|
||
!!! tip "大O复杂度表示法" | ||
**这就是大O时间复杂度表示法。大O时间复杂度实际上并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,所以,也叫作渐进时间复杂度(asymptotic time complexity),简称时间复杂度。** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters