为何要学数据结构和算法:算法
解决问题方法的效率,和数据的组织方式有关:数据结构
例子:如何在书架上摆放图书?
题眼:
操做一:新书怎么插入?
操做二:怎么找到某本指定的书?
方法一:随便放
操做一:哪里有空放哪里
操做二:找书就比较头疼了
方法二:按照书名的拼音字母顺序放
操做一:须要挨个位置移动
操做二:二分查找
方法三:把书架按类别分区,每一个类别内按照字母顺序放
操做一:搜索类别,二分查找肯定位置,挪出空位
操做二:搜索类别,二分查找肯定位置
思考:空间怎么分配,类别怎么分配
解决问题方法的效率,和空间的利用效率有关:数据结构和算法
例子:写方法,顺序打印从1到n的所有正整数 方法一:循环 function print(n){ for(var i=0;i<n;i++){ console.log(i); } return; } //数量级多大都能正常输出 方法二:递归 function print(n){ if(n){ print(n-1); console.log(n); } return; } //数量级到必定程度直接崩溃,由于递归很是耗费空间
解决问题方法的效率,和算法的巧妙程度有关:函数
例子:i*x的i次方 ,i取值从0~9,在x=1.1时计算他们的和 方法一:老老实实翻译成代码 function compute(n,a,x){ var result = a[0]; for(var i=1;i<=n;i++){ result += (a[i] * Math.pow(x,i)); } return result; } 方法二:提取公因数 function compute(n,a,x){ var result = a[n]; for(var i=n;i>0;i--){ result = a[i-1] + x*result; } return result; } 结果:这两种方法在分别屡次运行累加的时间,方法二比方法一快一个数量级
数据结构和算法的概念:ui
//什么是数据结构 数据对象:数据在计算机中的组织方式,包括逻辑结构和物理存储结构。 数据对象集的相关操做:数据对象一定与一系列加在其上的操做相关,完成这些操做所用的方法就是算法。 数据结构就描述了数据对象集及与其相关的操做集。
//什么是算法 算法是一个有限的指令集,接收一些输入,在有限步骤以后终止,产生输出。 算法的每一条指令都要有明确的目标、在计算机处理范围内、不依赖于任何一种语言及具体实现手段。
算法分析:spa
//空间复杂度S(n) 根据算法写成的程序在执行时占用存储单元的长度。 这个长度每每与输入数据的规模有关,空间复杂度太高可能致使内存超限,形成程序非正常中断。 //时间复杂度T(n) 根据算法写成的程序在执行是耗费时间的长度。 这个长度一般与输入数据的规模有关,时间复杂度太高的算法可能致使咱们有生之年都等不到运行结果。
时间复杂度的计算:翻译
一般状况下咱们关注:最坏状况复杂度和平均复杂度。 //复杂度的渐进表示法(空间复杂度也同样,这里省略) T(n) = O(f(n)) 表示算法时间复杂度的上界 T(n) = Ω(g(n))表示算法时间复杂度的下界 T(n) = θ(h(n))表示上界和下界同时适用 //时间复杂度函数优劣排序(从左到右,愈来愈慢) 1 < log n < n < n*log n < n^2 < n^3 < 2^n < n! //几个时间复杂度的计算要点 相加取大值:T1(n) + T2(n) = max(O(f1(n)),O(f2(n))) 相乘取乘积:T1(n) * T2(n) = O(f1(n) * f2(n)) n的k阶多项式:T(n) = θ(n^k) for循环:T(n) = 循环次数 * 循环体代码的复杂度 if-else:T(n) = max(if判断复杂度,if分支复杂度,else复杂度)
正常循环的时间复杂度:O(1)、O(n)、O(n^2) ……code
首先明确:常数项对时间增加影响不大,因此被忽略 function test1(){ console.log("hello"); } //T(n) = 1 → O(1) function test2(n){ for(var i=0;i<n;i++){ console.log("hello"); } } //T(n) = (n*1) → O(n) function test3(n){ for(var i=0;i<n;i++){ for(var j=0;j<n;j++){ console.log("hello"); } } } //T(n) = (n*n*1) → O(n^2) function test4(n){ //第一部分 T1(n) = (n*n*1) → O(n^2) for(var i=0;i<n;i++){ for(var j=0;j<n;j++){ console.log("hello"); } } //第二部分 T2(n) = (n*1) → O(n) for(var x=0;x<n;x++){ console.log("world"); } } //T(n) = max(T1(n^2),T2(n)) → O(n^2) function test5(n){ if(n>=0){ //第一部分 T1(n) = (n*n*1) → O(n^2) for(var i=0;i<n;i++){ for(var j=0;j<n;j++){ console.log("hello"); } } }else{ //第二部分 T2(n) = (n*1) → O(n) for(var x=0;x<n;x++){ console.log("world"); } } } //T(n) = max(T1(n^2),T2(n)) → O(n^2)
二分法的时间复杂度:logn对象
//在有序数列中查找target,利用二分法实现 function test(arr,target){ var left=0; var right = arr.length-1; while(left<=right){ var middle = Math.floor((left + right)/2); if(arr[middle]>target){ //中间值比target大,target在左边,序列变动为 left~middle-1 right = middle-1; }else if(arr[middle]<target){ //中间值比target小,target在右边,序列变动为 middle+1~right left = middle+1; }else{ //不大不小就是找到了 return middle; } } return -1; } //时间复杂度: //n + n/2 + n/4 + …… + n/(2^k) //令 n/(2^k) = 1,可得 k = log2n //T(n) = O(logn)