js 算法基本概念

83 阅读4分钟

真是到了某个阶段,在编程的某些瞬间,切实的体会到似乎“一切皆算法”……


程序设计 = 算法 + 数据结构

一 数据结构

数据结构是指互相之间存在一种或多种特定关系的数据元素的集合。

对于不同的逻辑,不同的数据结构可以使计算机的运行或存储效率大为提高,数据结构往往同高效的检索算法或索引技术有关。

概念术语

概念定义
数据能被计算机处理的符号或符号集合(原材料)
数据元素数据的基本单位
数据项组成数据元素的最小单位
数据对象性质相同的数据元素集合,是数据的子集
数据结构数据的组织方式
数据类型按照数据值的不同进行划分的可操作性数据

数据结构的四大类型

数据类型特征
线性结构数据元素之间的关系是一对一的且是一种先后的次序
集合结构数据元素之间没有任何关系,放在同一个被称作集合的容器内
树形结构数据元素之间的关系是一对多
图结构数据元素关系是多对多

二 算法

算法的五大特性

特性说明
有穷性经过一定的循环之后可以自行结束
确定性相同的输入只能有一个唯一的输出结果
可行性算法的每一步都必须可行
输入有0到多个输入参数
输出至少有一个输出

三 时间复杂度和空间复杂度

1. 复杂度

O 表示复杂度。

如下求和的代码示例:

function sum(n) {
    let total = 0;
    for(let i = 0; i < n; i++) {
        total += i;
    }
    return total;
}

假设每条语句执行的时间为 t, 则这个方法执行时间的计算步骤如下:

1) 第2行执行一次,时间为 t; 2) 第3、4行执行 n 次, 时间为 t * n * 2; 3) 第6行执行一次,时间为 t; 则总时间为 (2n + 2)t ;

如果用 f(n) 来表示代码的执行次数和数据规模的关系,可以写为:

f(n) = 2n + 2

当 n 趋于无穷大时,该公式同等于:

f(n) = n

使用 复杂度O表示法为:

O(n)

推导O表示法的基本规则:如果运行时间时常数,可用1表示;只保留最高阶项;如果最高阶项存在,可以省去最高阶项前的系数。

2. 时间复杂度

时间复杂度,是指随着 n 的增大,算法执行所需的时间的增长速度,可用 f(n)来描述。

表示代码实际执行时间与数据规模的关系,可以下面公式表示:

T(n) = O(f(n))

时间复杂度,实际就是当前算法所消耗的时间,所以它是衡量一个算法好坏的重要指标,一般情况下,随着规模 n 的增大,所消耗的时间 T(n) 增长最慢的算法为最好的算法。

常见的时间复杂度

复杂度级别描述
O(1)常数级最优,执行时间不受数据多少影响
O(n)线性级级还可以,执行时间等于元素个数
O(log)对数级 / 线性对数级还不错
O(n2)二次幂(n的2次方)有点慢,例如两层 for 循环
O(n3)三次幂(n的3次方)特别慢,例如矩阵乘法
O(2n)指数级(n次幂)超级慢,添加一点数据就会将时间托的很长
O!灾难级奇慢无比

3. 空间复杂度

空间复杂度,是对一个算法在运行过程中临时占用存储空间大小的量度,记作:

S(n) = O(f(n))

占用的存储空间可分为两种:

  • 固定部分: 代码本身占用的空间,及变量占用的空间。
  • 可变部分: 动态分布的空间,递归栈所需的空间。

示例:

function factorial(num){  
  if(num <= 0){  
    return 1;  
  }else{  
    return num*factorial(num-1);  
  }  
} 

固定部分:函数 factorial 占用的空间大小;

可变部分:输入输出数据占用的空间(num),函数运行期间为每个递归分配的空间(调用栈)。

所以此程序的空间复杂度可以理解为:函数空间 + num 空间 + 调用栈空间


参考: yancy__