前端初识算法

14天阅读挑战赛
前端初识算法_第1张图片

文章目录

  • 概览
  • 前言
  • 算法导读
  • 初识算法
  • 算法复杂性
    • 算法特征
    • 好算法的标准
    • 时间复杂度
    • 空间复杂度
  • 结束语


概览

  • ✨ 食用时间: 10分钟
  • ✨ 难度: 「简单」,别跑,看完再走
  • ✨ 食用价值: 了解什么是算法,打开算法之门
  • ✨ 铺垫知识: JavaScript

前言

努力是为了不平庸~
算法学习有些时候是枯燥的,这一次,让我们先人一步,趣学算法!欢迎记录下你的那些努力时刻(算法学习知识点/算法题解/遇到的算法bug/等等),在分享的同时加深对于算法的理解,同时吸收他人的奇思妙想,一起见证技术er的成长~

算法导读

《趣学算法-第2版》一书中对算法这么描述
如果说数学是皇冠上的一颗明珠,那么算法就是这颗明珠上的光芒,算法让这颗明珠更加熠熠生辉,为科技进步和社会发展照亮了前进的路。数学是美学,算法是艺术。走进算法的人,才能体会它的无穷魅力。描述非常形象且令人记忆深刻。

初识算法

瑞士著名的科学家 Niklaus Wirth 教授曾提出:数据结构+算法=程序
数据结构是程序的骨架,算法是程序的灵魂。
在生活中,算法无处不在。每天早上起来,刷牙、洗脸、吃早餐,都在算着时间,以免上班或上课迟到;去超市购物,在资金有限的情况下,考虑先买什么、后买什么。算算是否超额;在生活的方面面其实都用到了算法!

对于前端开发来说,大多数会说:算法是后端的搞的事情,前端不用算法,算法没啥用!然而非也,当我们处理后端小伙伴返回到前端的数据时,进行的数据处理就用到了算法。在处理数据的过程中是声明一个Map还是一个普通的Array数组,是使用嵌套的的循环还是使用递归等等都需要我们去思考选择,对于算法既熟悉又陌生。

算法复杂性

算法只是对问题求解方法的一种描述,它不依赖于任何一种语言,既可以用自然语言、程序设计语言(C、C++、Java、Javascript、Python等)描述,也可以用流程图、框图来表示。通常情况下,为了更清楚地说明算法的本质,我们会去除计算机语言的语法规则和细节,采用“伪代码”来描述算法。“伪代码”介于自然语言和程序设计语言之间,它更符合人们的表达方式,容易理解,但它不是严格的程序设计语言。如果要上机调试,则需要转换成标准的计算机程序设计语言才能运行。

算法特征

  • 有穷性 :算法是由若干条指令组成的有穷序列,总是在执行若干次后结束,不可能永不停止。
  • 确定性 :每条语句都有确定的含义,无歧义。
  • 可行性 :算法在当前环境条件下可以通过有限次运算来实现。
  • 输入\输出 :有零个或多个输入以及一个或多个输出。

好算法的标准

  • 正确性 :正确性是指算法能够满足具体问题的需求,程序运行正常,无语法错误,能够通过典型的软件测试,达到预期。
  • 易读性 :算法遵循标识符命名规则,简洁易懂,注释语句恰当适量,方便自己和他人阅读,便于后期调试和修改。
  • 健壮性 :算法对非法数据及操作有较好的反应和处理。例如,在学生信息管理系统中登记学生年龄时,若将21岁误输入为210岁,则系统应该有错误提示。
  • 高效性 :高效性是指算法运行效率高,即算法运行所消耗的时间短。
  • 低存储性 :低存储性是指算法所需的存储空间小。对于像手机、平板电脑这样的嵌入式设备,算法如果占用空间过大,则无法运行。算法占用的空间大小被称为空间复杂度

时间复杂度

表示代码的运行时间,通过代码的执行次数来表示,大 O 时间复杂度表示法 实际上并不具体表示代码真正的执行时间,而是表示 代码执行时间随数据规模增长的变化趋势,所以也叫 渐进时间复杂度,简称 时间复杂度

举个栗子

function fn1(){
    console.log("砍了一棵树")
    console.log("砍了一棵树")
}

fn1函数执行次数2次

function fn2(n){
    for( let i = 0; i < n; i++){
        console.log("砍了一棵树")
    }
    return "一棵树"
}

fn2函数执行次数

let = 0                   :执行 1 次
i < n                     : 执行 n+1 次
i++                       : 执行 n 次
console.log("砍了一棵树")  : 执行 n 次
return "一棵树"            : 执行 1

总执行次数为1+n+1+n+1+n+1 = 3n+3 次。代码执行时间为T(n),执行次数 f(n) ,因此我们得到一个公式:T(n) = O( f(n) ) 大O表示法

n 是输入数据的大小或者输入数据的数量  
T(n) 表示一段代码的总执行时间   
f(n) 表示一段代码的总执行次数   
O  表示代码的执行时间 T(n)执行次数f(n) 成正比
  • fn1函数执行2次,用O(2)表示
  • fn2函数执行3n+3 次,用O(3n+3 )表示
  • 简化执行时间的估值得到最终时间复杂度
  • 如果只有常数直接估算为1,O(2) 的时间复杂度就是 O(1),一般情况下,只要算法里没有循环和递归,就算有上万行代码,时间复杂度也是O(1)
  • O(3n+3) 里常数3对于总执行次数的几乎没有影响,直接忽略不计,系数 3 影响也不大,因为3n和n都是一个量级的,所以作为系数的常数3也估算为1或者可以理解为去掉系数,所以 O(3n+3) 的时间复杂度为 O(n)
  • 如果是多项式,只需要保留n的最高次项O(10n³ + 10n² + n ),这个复杂度里面的最高次项是n的3次方。因为随着n的增大,后面的项的增长远远不及n的最高次项大,所以低于这个次项的直接忽略不计,常数也忽略不计,简化后的时间复杂度为 O(n³)

时间复杂度右快到慢

  • O(1) 常数复杂度
function fn(n){
	const a = 1;
	const b = 2;
	console.log(1);
	console.log(2);
	console.log(3);
	--------------
	console.log(10000);
}
  • O(logn) 对数复杂度
function fn(){
	let i = 1;
	const n = 6;
	while (i < n) {
	  i = i * 2;
	}
}
  • O(n) 线性时间复杂度
function fn(n){
    for( let i = 0; i < n; i++ ){
            console.log("砍了一棵树")
    }
}
  • O(nlogn) 线性对数复杂度
function fn(){
for (let i = 0; i <= n; i++) {
    while (j < i) {
        j = j * 2;
    }
 }
}
  • O(n²) 平方
function fn(n){
    for( let i = 0; i < n; i++){
        for( let j = 0; j < n; j++){
            console.log("砍了一棵树")
        }
    }
}
  • O(n³) 立方
function fn(){
for(x=1; i <= n; x++){
   for(i = 1; i <= n; i++) {
       j = i;
       j++;
       for(i = 1; i <= n; i++) {
       j = i;
       j++;
    	}
      }
	}
}
  • O(2n) 指数
  • O(n!) 阶乘

x轴表示n值,y轴表示时间复杂度
前端初识算法_第2张图片

空间复杂度

空间复杂度表示代码占用多少内存

O(1)常数阶:不会因为代码行数而变换,空间复杂度表示为O(1)

function fn(){
    console.log("1")
    console.log("2")
    console.log("3")
    ......
    console.log("10000")
}

O(n)线性阶:传入的参数n越大占用的内存越高

function fn(n){
    let arr = []
    for( let i = 1; i < n; i++ ) {
        arr.push(i)
    }
}

O(n²)平方阶:

function fn(n){
 let index=0
 var arr=[]
 function print(n) {
  for(var i=0;i<n;i++){
    for(var i=0;i<n;i++){
    	arr[index++]=1
  	  }
	 }
   }
}

结束语

希望本文对你有一点点帮助,如果有用请点个赞吧 ~

你可能感兴趣的:(算法,算法,前端)