javascript前端该如何准备数据结构和算法?code秘密花园

实际上,当你了解了“数据结构”和“算法”存在的真正意义,以及一些实际的应用场景,对它有了一个整体的认知之后,你可能会对它产生强烈的兴趣。当然,它带将带给你的收益也是相当可观的。

很多前端同学在看到“数据结构”和“算法”后会有一定的抵触心理,或者尝试去练习,但是被难倒,从而放弃。

这很大一部分原因是因为你还不够了解学习他们的意义,或者没有掌握合理的练习方法。

后面我也会针对所有常见的数据结构和算法分类,进行全方位的梳理。

数据结构和算法的种类非常之多,拿树举例,树的种类包括:二叉树、B树、B+树、Trie树、红黑树等等,本文只选择了二叉树。

本文选择的数据结构和算法的类别均是出现频率最高,以及应用最广的类别。

另外,做题时找对典型题目非常重要,可以让你更快速更高效的掌握知识,本文后面也会给出每种类型的典型题目供大家参考。

另外,我会在后面长期更新一个前端算法的专栏,对每类数据结构和算法进行详细的讲解,敬请期待。

在学习某块内容之前,我们一定要首先明确为什么要学,而不是盲目的跟风。

这将更有利于你从学习的过程中获得收益,而且会为你的学习带来动力。

首先明确一点,学习数据结构和算法不一定就是记住二叉树、堆、栈、队列等的解题方法也不是死记硬背一些题目,如果你仅仅停留在这样的表面思想,那么你学习起来会非常痛苦。

计算机只是一个很冰冷的机器,你给他下发什么样的指令,它就能作出什么样的反应。

而开发工程师要做的是如何把实际的问题转化成计算机的指令,如何转化,来看看《数据结构》的经典说法:

所以,很重要的一点,数据结构和算法对建立解决问题的思想非常重要。

这是非常现实的一点,也是很多前端学习数据结构和算法的原因。

一般对待算法的态度会分为以下几类:

Google、Microsoft等知名外企在面试工程师时,算法是起决定性因素的,前端工程师也是一样,基本是每一轮都会考察,即使你有非常强的背景,也有可能因为一两道算法答的不好而与这样的企业失之交臂。

第二类,算法占重要因素的,国内的某些大厂在面试时,也会把数据结构和算法作为重要的参考因素,基本是面试必考,如果你达不到一定的要求,会直接挂掉。

第三类,起加分作用,很多公司不会把数据结构和算法作为硬性要求,但是也会象征性的出一些题目,当你把一道算法题答的很漂亮,这绝对是加分项。

可见,学好数据结构和算法对你跳槽更好的公司或者拿到更高的薪水,是非常重要的。

了解了数据结构和算法的重要性,那么究竟该用什么样的方法去准备呢?

在学习和练习之前,你一定要对数据结构和算法做一个全方位的了解,对数据结构和算法的定义、分类做一个全面的理解,如果这部分做的不好,你在做题时将完全不知道你在做什么,从而陷入盲目寻找答案的过程,这个过程非常痛苦,而且往往收益甚微。

本文后面的章节,我会对常见的数据结构和算法做一个全方位的梳理。

当你对数据结构和算法有了一个整体的认知之后,就可以开始练习了。

注意,一定是分类练习!分类练习!分类练习!重要的事情说三遍。

我曾见过非常多的同学带着一腔热血就开始刷题了,从leetcode第一题开始,刚开始往往非常有动力,可能还会发个朋友圈或者沸点什么的,然后就没有然后了。

因为前几题非常简单,可能会给你一定的自信,但是,按序号来的话,很快就会遇到hard。或者有的人,干脆只刷简单,先把所有的简单刷完。

但是,这样盲目的刷题,效果是非常差的,有可能你坚持下来,刷了几百道,也能有点效果,但是整个过程可能非常慢,而且效果远远没有分类练习要好。

在对一个类型针对练习一些题目之后,你就可以发现一定的规律,某一些题目是这样解,另一些题目是那样解...这是一个很正常的现象,每种类型的题目肯定是存在一定规律的。

这时候就可以开始对此类题目进行总结了,针对此类问题,以及其典型的题目,发现的解题方法,进行总结。当下次你再遇到这种类型的题目,你就能很快想到解题思路,从而很快的解答。

所以,当你看到一个题目,首先你要想到它属于哪种数据结构或算法,然后要想到这是一个什么类型的问题,然后是此类问题的解决方法。

如果你看到一个新的问题还不能做到上面这样,那说明你对此类题目的掌握程度还不够,你还要多花一些经历来进行练习。

没有循环语句,记作O(1),也称为常数阶。只有一重循环,则算法的基本操作的执行频度与问题规模n呈线性增大关系,记作O(n),也叫线性阶。

一个程序的空间复杂度是指运行完一个程序所需内存的大小。利用程序的空间复杂度,可以对程序的运行所需要的内存多少有个预先估计。

一个程序执行时除了需要存储空间和存储本身所使用的指令、常数、变量和输入数据外,还需要一些对数据进行操作的工作单元和存储一些为现实计算所需信息的辅助空间。

数据结构这个词相信大家都不陌生,在很多场景下可能都听过,但你有没有考虑过“数据结构”究竟是一个什么东西呢?

一般你可以从两个维度来理解它,逻辑结构和存储结构。

简单的来说逻辑结构就是数据之间的关系,逻辑结构大概统一的可以分成两种:线性结构、非线性结构。

线性结构:是一个有序数据元素的集合。其中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。

常用的线性结构有:栈,队列,链表,线性表。

—非线性结构:各个数据元素不再保持在一个线性序列中,每个数据元素可能与零个或者多个其他数据元素发生联系。

常见的非线性结构有二维数组,树等。

逻辑结构指的是数据间的关系,而存储结构是逻辑结构用计算机语言的实现。常见的存储结构有顺序存储、链式存储、索引存储以及散列存储。

例如:数组在内存中的位置是连续的,它就属于顺序存储;链表是主动建立数据间的关联关系的,在内存中却不一定是连续的,它属于链式存储;还有顺序和逻辑上都不存在顺序关系,但是你可以通过一定的方式去放问它的哈希表,数据散列存储。

树是用来模拟具有树状结构性质的数据集合。根据它的特性可以分为非常多的种类,对于我们来讲,掌握二叉树这种结构就足够了,它也是树最简单、应用最广泛的种类。

平衡二叉树:左右子树深度之差大于1

用一组任意存储的单元来存储线性表的数据元素。一个对象存储着本身的值和下一个元素的地址。

链表在开发中也是经常用到的数据结构,React16的FiberNode连接起来形成的FiberTree,就是个单链表结构。

对于单链表,因为我们只能在一个方向上遍历链表,所以第一种情景可能无法工作。然而,第二种情景,也被称为慢指针和快指针技巧,是非常有用的。

双链还有一个引用字段,称为prev字段。有了这个额外的字段,您就能够知道当前结点的前一个结点。

数组是我们在开发中最常见到的数据结构了,用于按顺序存储元素的集合。但是元素可以随机存取,因为数组中的每个元素都可以通过数组索引来识别。插入和删除时要移动后续元素,还要考虑扩容问题,插入慢。

数组与日常的业务开发联系非常紧密,如何巧妙的用好数组是我们能否开发出高质量代码的关键。

在上面的数组中,我们可以通过索引随机访问元素,但是在某些情况下,我们可能要限制数据的访问顺序,于是有了两种限制访问顺序的数据结构:栈(后进后出)、队列(先进先出)

哈希的基本原理是将给定的键值转换为偏移地址来检索记录。

键转换为地址是通过一种关系(公式)来完成的,这就是哈希(散列)函数。

虽然哈希表是一种有效的搜索技术,但是它还有些缺点。两个不同的关键字,由于哈希函数值相同,因而被映射到同一表位置上。该现象称为冲突。发生冲突的两个关键字称为该哈希函数的同义词。

例如下面的题目:

堆的底层实际上是一棵完全二叉树,可以用数组实现

排序或许是前端接触最多的算法了,很多人的算法之路是从一个冒泡排序开始的,排序的方法有非常多中,它们各自有各自的应用场景和优缺点,这里我推荐如下6种应用最多的排序方法,如果你有兴趣也可以研究下其他几种。

查找是计算机中最基本也是最有用的算法之一。它描述了在有序集合中搜索特定值的过程。

二分查找维护查找空间的左、右和中间指示符,并比较查找目标或将查找条件应用于集合的中间值;如果条件不满足或值不相等,则清除目标不可能存在的那一半,并在剩下的一半上继续查找,直到成功为止。如果查以空的一半结束,则无法满足条件,并且无法找到目标。

递归是一种解决问题的有效方法,在递归过程中,函数将自身作为子例程调用。

你可能想知道如何实现调用自身的函数。诀窍在于,每当递归函数调用自身时,它都会将给定的问题拆解为子问题。递归调用继续进行,直到到子问题无需进一步递归就可以解决的地步。

为了确保递归函数不会导致无限循环,它应具有以下属性:

一些问题使用递归考虑,思路是非常清晰的,但是却不推荐使用递归,例如下面的几个问题:

这几个问题使用递归都有一个共同的缺点,那就是包含大量的重复计算,如果递归层次比较深的话,直接会导致JS进程崩溃。

你可以使用记忆化的方法来避免重复计算,即开辟一个额外空间来存储已经计算过的值,但是这样又会浪费一定的内存空间。因此上面的问题一般会使用动态规划求解。

递归是一种思想,而非一个类型,很多经典算法都是以递归为基础,因此这里就不再给出更多问题。

广度优先搜索(BFS)是一种遍历或搜索数据结构(如树或图)的算法,也可以在更抽象的场景中使用。

它的特点是越是接近根结点的结点将越早地遍历。

例如,我们可以使用BFS找到从起始结点到目标结点的路径,特别是最短路径。

在BFS中,结点的处理顺序与它们添加到队列的顺序是完全相同的顺序,即先进先出,所以广度优先搜索一般使用队列实现。

和广度优先搜索一样,深度优先搜索(DFS)是用于在树/图中遍历/搜索的一种重要算法。

与BFS不同,更早访问的结点可能不是更靠近根结点的结点。因此,你在DFS中找到的第一条路径可能不是最短路径。

在DFS中,结点的处理顺序是完全相反的顺序,就像它们被添加到栈中一样,它是后进先出。所以深度优先搜索一般使用栈实现。

从解决问题每一步的所有可能选项里系统选择出一个可行的解决方案。

在某一步选择一个选项后,进入下一步,然后面临新的选项。重复选择,直至达到最终状态。

回溯法解决的问题的所有选项可以用树状结构表示。

动态规划往往是最能有效考察算法和设计能力的题目类型,面对这类题目最重要的是抓住问题的阶段,了解每个阶段的状态,从而分析阶段之间的关系转化。

适用于动态规划的问题,需要满足最优子结构和无后效性,动态规划的求解过程,在于找到状态转移方程,进行自底向上的求解。

贪心算法:对问题求解的时候,总是做出在当前看来是最好的做法。

适用贪心算法的场景:问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。这种子问题最优解成为最优子结构

贪心算法与动态规划的不同在于它对每个子问题的解决方案都作出选择,不能回退,动态规划则会保存以前的运算结果,并根据以前的结果对当前进行选择,有回退功能,而回溯算法就是大量的重复计算来获得最优解。

有很多算法题目都是可以用这三种思想同时解答的,但是总有一种最适合的解法,这就需要不断的练习和总结来进行深入的理解才能更好的选择解决办法。

这部分是与前端开发贴近最紧密的一部分了,在写业务代码的同时,我们也应该关心一些类库或框架的内部实现。

大多数情况下,我们在写业务的时候不需要手动实现这些轮子,但是它们非常考察一个前端程序员的编码功底,如果你有一定的算法和数据结构基础,很多源码看起来就非常简单。

下面我拣选了一些问题:

Readingmakesafullman,conferenceareadyman,andwritinganexactman.

THE END
1.朱娜斐编译原理复习笔记北京工业大学软件学院说明 笔记大部分内容来自 参考资料[1], 看了B站上中科大华保健老师的编译原理课视频( 参考资料[2]),补充完善了DFA的代码表示、Hopcroft 算法、文法重写、LL(1)算法、LR算法等内容 有许多知识是结合了自己的理解进行整理,所以可能会有错误之处 再往后因为时间问题就有点烂尾了 https://www.jianshu.com/p/f25c1315af34
2.人工智能技术基础系列之:知识图谱51CTO博客核心算法原理和具体操作步骤以及数学模型公式详细讲解 具体代码实例和详细解释说明 未来发展趋势与挑战 附录常见问题与解答 1.1 知识图谱的应用场景 知识图谱技术在人工智能领域具有广泛的应用,主要包括以下几个方面: 语义搜索:知识图谱可以帮助搜索引擎更好地理解用户的查询意图,并提供更相关的搜索结果。例如,当用户搜索“https://blog.51cto.com/universsky/8996522
3.算法是什么?初学者必看!,教育,高等教育,好看视频算法是什么?初学者必看! 百度文库 53万粉丝 · 76万个视频百度文库官方账号 关注 接下来播放自动播放 01:05 冉莹颖11岁儿子身高只有136 十二不惑 13万次播放 · 452次点赞 01:06 61岁钱小豪自曝健康状况,否认患癌以及糖尿病,透露暴瘦40磅原因 星知道STAR 5.3万次播放 · 122次点赞 12:02 战火连天:女土匪https://haokan.baidu.com/v?pd=wisenatural&vid=6851353270577964344
4.软件工程之软件设计③(概要设计说明书,详细设计说明书)总体设计(概要设计)侧重点在于整体的把控,即整个软件中模块的组成以及各个模块的调用关系。通过结构化设计方法(SD方法)来进行描述,让使用者可以很清晰的看到概要设计人员想要表达的内容,最后形成的文档是概要设计说明书。 详细设计则是侧重于每个独立模块中的数据结构,算法,接口,测试的设计,通过各种软件开发工具辅助来完https://cloud.tencent.com/developer/article/2081756
5.《100以内的加法和减法》教案学生在一年级学会了两位数加一位数和两位数加整十数的口算,为学生理解两位数不进位加法笔算的的算理和算法做好了准备,利用知识的迁移,通过学具的操作,经历活动的探究,体验成功的快乐。 教学重点:掌握两位数不进位加法的笔算方法并能正确计算。 教学难点:理解相同数位上的数才能相加的道理。 https://www.wenshubang.com/jiaoan/2980367.html
6.万字干货!15个著名的设计心理学原理和应用深度解析!0 无需说明书 乔布斯曾说过:“苹果应该创造所有人都可以使用的产品,即使没有用户指南”。 1 一看就会 简单易懂,看一眼就明白你想说什么,不用教学就知道怎么用。 2 秒法则 所谓“2 秒法则”,是指用户在使用某类系统时的等待时长不超过 2 秒。在极短的时间内展示重要信息,给用户留下深刻的第一印象。这里的https://www.uisdc.com/15-principles-of-psychology/
7.自动搜索算法(带源码和详细说明)资源Ransac算法说明及源代码,并包含使用实例。改代码书写严谨,并有详细的使用说明。 基于Matlab实现A星算法源码+项目说明+超详细注释.zip 浏览:14 5星 · 资源好评率100% 【资源说明】 基于Matlab实现A星算法源码+项目说明+超详细注释.zip 算法介绍 A*算法最初发表于1968年,由Stanford研究院的Peter Hart, Nils Nilssohttps://download.csdn.net/download/weixin_39247141/10609301
8.小米运动手表Color使用说明小米运动手表Color评测而且针对运动场景,小米手表Color运动版内置了12nm制程工艺的高端四模定位芯片,支持GPS、GLONASS、GAlileo、北斗四大全球卫星定位系统,搭配定制里程优化算法,可进一步提升运动轨迹和里程精度,更准确的记录运动数据。比如我实际测试键走,围着小区走一圈,轨迹记录的非常精准,户外定位也很快。日常计步,实测200步走下来,竟然一步https://post.smzdm.com/ju/ad4xq04/
9.河南省济源第一中学河南省济源第一中学始建于1926年,是“全国文明校园”“河南省示范性普通高中”“河南省普通高中多样化发展示范校”。https://www.hnjyyz.com/
10.这是一份通俗易懂的知识图谱技术与应用指南机器之心首先需要说明的一点是,有可能不少人认为搭建一个知识图谱系统的重点在于算法和开发。但事实并不是想象中的那样,其实最重要的核心在于对业务的理解以及对知识图谱本身的设计,这就类似于对于一个业务系统,数据库表的设计尤其关键,而且这种设计绝对离不开对业务的深入理解以及对未来业务场景变化的预估。 当然,在这里我们https://www.jiqizhixin.com/articles/2018-06-20-4
11.ADMM算法的详细推导过程是什么?具体证明其实没什么技术难度,顶多就是algebra稍微有点绕。这也是ADMM算法分析的一般特点,我们这还是最https://www.zhihu.com/question/309568920/answer/580226096