当前位置: 首页 > Web前端 > HTML5

数据结构与算法JavaScript(不定时更新)

时间:2023-04-05 23:11:26 HTML5

楼楼不是计算机专业的,但他还是喜欢计算机。如个人理解有偏差,敬请批评指正!数据结构和算法一直是我的薄弱环节。相信大部分前端工程师在这方面可能都有一些弱点。另外,数据结构和算法有点枯燥。立个flag,过三天就忘了。也是时不时的,好吧,还是收起老妈的唠叨吧,楼楼毕竟还是个美少女,哈哈哈~在JS里面,我知道的稍微复杂一点的数据结构有数组和对象。但是如果你看大多数语言,你会发现你知道的太少了。当然,我们可能会用到很少的以下内容。不过个人觉得这些都是思想沉淀,发生的变化影响会很微妙,所以应该算是默默滋润的东西,哈哈哈~楼楼借用数据结构和算法的JavaScript描述书,当时写这篇文章的~==开始------------------------------------------------------------------------------------------==关于那些定义:数组:存储元素的线性集合(collection),元素可以通过索引任意访问,索引通常是一个数字,用来计算元素之间存储位置的偏移量。数组的那些方法(js)es6addArray.from()//如果不支持伪数组到数组的转换,我们也可以通过call和apply改变this的方向,从而实现伪数组的方法-arraycallingarrayArray.of()//将一组值转换成一个数组Array.prototype.copyWithin(target,start=0,end=this.length)//将指定位置的成员复制到其他positions(原来的成员会被覆盖),然后返回当前数组。也就是说,使用这个方法会修改当前数组。target(必需):开始替换数据的位置。如果是负值,则表示倒数。start(可选):从该位置开始读取数据,默认为0。如果为负值,则表示倒数。end(可选):到达该位置前停止读取数据,默认等于数组长度。如果是负值,则表示倒数。Array.find(item=>item>0)在数组中找到满足条件的元素并返回,如果没有满足条件的元素,则返回undefineArray.findIndex(item=>item>0)返回的位置第一个满足条件的数组成员,如果没有成员满足条件则返回-1。Array.fill()//用一个值填充数组entries()[pairkeyvalue]keys()[pairkey]values()[pairvalue]用于遍历数组。它们都返回一个迭代器对象。Array.includes()这个方法必须硬推,返回一个布尔值,表示一个数组是否包含特定的值,类似于字符串的includes方法。还有这些,就不细说join()push()和pop()shift()和unshift()sort()reverse()concat()slice()splice()indexOf()和lastIndexOf()(ES5新增)forEach()(ES5新增)map()(ES5新增)filter()(ES5新增)every()(ES5新增)some()(ES5新增)reduce()和reduceRight()(ES5新增)比较复杂的数组应该是二维和多维数组。JavaScript只支持一维数组,但是可以通过在数组中存储数组元素来轻松创建多维数组。列表列表是一组有序的数据。每个列表中的数据项称为元素。在JavaScript中,列表中的元素可以是任何数据类型。列表中可以存储的元素个数事先没有限制,实际使用中的元素个数受程序内存的限制。列表有前面和后面(分别对应前端和结尾)。堆栈是一种特殊的列表。栈中的元素只能通过链表的一端访问,称为栈顶。堆栈被称为后进先出(LIFO,last-in-first-out)数据结构。push()方法用于入栈,pop()方法用于出栈。队列队列是先进先出(FIFO)数据结构。插入操作也称为入队,删除操作也称为出队。入队操作在队尾插入新元素,出队操作删除队头元素。链表==背景:在很多编程语言中,数组的长度是固定的,所以当数组充满数据后,再添加新的元素会非常困难。在数组中,添加和删除元素也很麻烦,因为数组中的其他元素需要向前或向后翻译以反映数组刚刚添加或删除。但是JavaScript数组不存在上述问题,因为使用split()方法不需要访问数组中的其他元素。==链表是节点的集合。每个节点都使用一个对象引用来指向其后继节点。指向另一个节点的引用称为链。我们常说的链表就是单向链表。双向链表示意图:循环链表示意图。通过这三张图,希望大家对链表有一个初步的了解。字典字典是一种数据结构,它以键值对的形式存储数据。通常,当人们谈论字典时,他们会谈论电话簿。我觉得它更像是JS中的一个Object类,一个键对应一个值。但是很多教材会说Dictionary类的基础是Array类,而不是Object类。好的,没关系!毕竟,JavaScript中的一切都是对象。Hash散列是一种常用的数据存储技术,散列后的数据可以快速插入或检索。用于哈希的数据结构称为哈希表。在哈希表上插入、删除和取数据的速度非常快,但是对于查找操作来说效率很低,比如在一组数据中寻找最大值和最小值。这些操作不得不求助于其他数据结构,二叉搜索树是一个不错的选择。即使使用高效的哈希函数,仍然存在将两个键映射到相同值的可能性。这种现象叫做碰撞(collision)==hashTable的实现是一个典型的基于散列的数据结构,在这里如果你有兴趣,也可以看看霍纳的算法==当一个散列函数产生相同的输出为多个输入,发生碰撞。碰撞解决方案:开链法和线性检测法开链法是指在实现哈希表的底层数组中,每个数组元素都是一个新的数据结构,比如另一个数组,这样可以存储多个key。使用这种技术,即使两个键具有相同的散列值,它们仍然存储在相同的位置,它们只是在第二个数组中的位置不同。线性探测属于一种更通用的哈希技术:开放寻址哈希。当发生冲突时,线性探测检查哈希表中的下一个位置是否为空。如果为空,则将数据存入该位置;如果不为空,则继续检查下一个位置,直到找到一个空位置。该技术基于这样一个事实,即每个哈希表都会有许多可用于存储数据的空单元格。集合集合由一组无序但相关的成员组成,每个成员在集合中只能出现一次。?不包含任何成员的集合称为空集,而完整集是包含所有可能成员的集合。?如果两个集合的成员相同,则称这两个集合是相等的。?如果一个集合的所有成员都属于另一个集合,则前一个集合称为后一个集合的子集。集合的基本操作如下。?联合将两个集合的成员组合成一个新集合。?交集两个集合的共存成员形成一个新集合。?Complement属于一个集合但不属于另一个集合的成员树:树是一种非线性数据结构,它以分层方式存储数据。树:树是一种非线性数据结构,它以分层方式存储数据。其中树中经常提到的应该就是二叉树了。提到二叉树补充点东西,这个是我朋友写的,我觉得写的比较好。拿出来分享一下~一个更适合表达时序集合的数据结构树。..树最好。为什么?二叉搜索树自然可以用于排序二分搜索。左子树小于根节点,右子树大于根节点。树的高度就是最大搜索次数,是一个很小的常量。二叉搜索树改进为二叉平衡搜索树二叉搜索树的缺点是什么?树的构建受数据收集顺序的影响。极端情况下退化为单项链表,失去二叉树的意义,检索复杂度退化为顺序遍历。因此,二叉搜索树需要平衡,即左右子树的高度应该相似。二叉平衡搜索树改进为B树,搜索复杂度为log2(n)。如果想进一步减少搜索次数,也就是树的高度怎么办?增大对数的底数,底数越大,对数值越小。因此改进为m阶树,约定非根节点的key个数(m/2~m),成为B树。B-tree改进为B+树B-tree的缺点:B-tree的每个节点都包含数据记录或指针,占用大量内存空间,重复换页导致内存访问效率低下;典型的业务场景是查询一定范围的数据记录,不仅仅是单行,B-tree比较慢。改进措施:树的非叶子节点不包含数据记录,叶子节点包含指向数据记录的指针(聚簇索引的key),减少了索引树整体占用的内存,提高了内存访问效率;所有的数据记录都被叶子节点覆盖,叶子节点之间的节点自然有序,通过单项链表连接起来,方便遍历一个范围的记录。改进后为B+树。Mariadb-10.3使用B+树。B+树改进为B*树B+树的缺点:每个非叶子节点可能只包含m/2个键,其中一半是空闲的,内存占用低。改进措施:将非叶子节点的最小键数增加到2m/3,提高内存占用率。付出的代价是非叶子节点需要添加指向兄弟节点的指针,以方便节点分裂和合并。改进后为B*树。一些基于B+树的推理sel??ect*fromxxxoffsetNlimitM,没有特别关注N对效率的影响。如果N可能很大,比如超过10000,那么冷热数据分开维护,保证N不会太大。select*fromxxxorderbyaorderbyb,联合索引受索引树的影响,自然需要左匹配的原则,可以使用联合索引时搜索效率非常高。主键用uuid好还是int好?Innobase数据引擎下单调增长的int比较好。uuid32字节,用于索引必须大于int4字节,索引树占用的内存越大,内存访问效率越低,所以uuid越差;innobase文件物理存储结构的内容是主键索引(聚集索引),单调递增主键保证数据在连续的磁盘页上不断追加,内存访问效率高,而uuid导致新数据随机插入磁盘页,数据移动量大,内存访问效率低。总的来说uuid很差。当然id本身在生成的时候也存在锁竞争等问题。如果对树状结构感兴趣,可以进一步探索,因为这片水比较深。图和图算法图由边的集合和顶点的集合组成。