JavaScript 与简单算法
真的是一些 JavaScript 与简单算法,具体的看下方评论区。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 杂七杂八问题以及解决方案记录
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
真的是一些 JavaScript 与简单算法,具体的看下方评论区。
上一篇: 杂七杂八问题以及解决方案记录
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(12)
大神,选择排序是不稳定的,是什么意思?
我运行了一下:
效果上看是正确的啊
@caiyongmin 按一般的实现方式,直接在数组里交换的话,选择排序是不稳定的。
如下:
所以说不稳定。
我看了你今天在知乎发的招聘信息,你看看我能去不?工资随便开。不给也可以,实在不想一个人脱产自学啦,想尽早加入一个团队,找到组织。那些新技术、新框架rxjs,http2,typescript,react native,ionic等等都想学啊。先稍微自我介绍一下,92年,自动化专业,15年毕业,热爱google,电脑基础常识还是必须有的,今年五月份才开始学前端的,基本上会的东西都在github里。 --ps:https://www.cform.io/
这个单页应用也很复杂
3.6.2二叉搜索树
上面一段基本是在介绍树相关的概念,接下来配合概念用JS代码实现树的相关操作。
参考:
3.6.1 二叉树与先序/中序/后序遍历
遍历二叉树(Traversing Binary Tree):是指按指定的规律对二叉树中的每个结点访问一次且仅访问一次。
二叉树的遍历主要分三种:
3.6 树
树(Tree)是n(n>=0)个结点的有限集。n=0时称为空树。在任意一棵非空树中:
若将树中每个结点的各子树看成是从左到右有次序的(即不能互换),则称该树为有序树(OrderedTree);否则称为无序树(UnorderedTree)。注意:若不特别指明,一般讨论的树都是有序树。
术语:
3.7 二叉树
1. 二叉树的定义:二叉树的每个节点至多只有二棵子树(不存在度大于2的节点),二叉树的子树有左右之分,次序不能颠倒。
二叉树的第
i
层至多有2^(i-1)
个节点;深度为k
的二叉树至多有2^k-1
个节点;对任何一棵二叉树T,如果其终端节点数为n0
,度为2的节点数为n2
,则n0=n2+1
。二叉树的存储结构
顺序存储结构
用一组连续的存储单元依次自上而下,自左至右存储完全二叉树上的结点元素,即将二叉树上编号为i的结点元素存储在加上定义的一维数组中下标为i-1的分量中。“0”表示不存在此结点。这种顺序存储结构仅适用于完全二叉树。因为,在最坏情况下,一个深度为k且只有k个结点的单支树(树中不存在度为2的结点)却需要长度为2的n次方-1的一维数组。
顺序:
[1, 2, 3, 4, 5, , 6, , , 7]
链式存储结构
二叉树的结点由一个数据元素和分别指向其左右子树的两个分支构成,则表示二叉树的链表中的结点至少包含三个域:数据域和左右指针域。有时,为了便于找到结点的双亲,还可在结点结构中增加一个指向其双亲结点的指针域。利用这两种结构所得的二叉树的存储结构分别称之为二叉链表和三叉链表。 在含有n个结点的二叉链表中有n+1个空链域,我们可以利用这些空链域存储其他有用信息,从而得到另一种链式存储结构---线索链表。
链式:
{ data, left, right}
2. 满二叉树:除最后一层无任何子节点外,每一层上的所有结点都有两个子结点。也可以这样理解,除叶子结点外的所有结点均有两个子结点。节点数达到最大值,所有叶子结点必须在同一层上。
满二叉树的性质:
3. 完全二叉树:若设二叉树的深度为h,除第 h 层外,其它各层 (1~(h-1)层) 的结点数都达到最大个数,第h层所有的结点都连续集中在最左边,这就是完全二叉树。
4. 二叉查找树
二叉查找树(英语:Binary Search Tree),也称二叉搜索树、有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低。为 O(log n) 。二叉查找树是基础性数据结构,用于构建更为抽象的数据结构,如集合、multiset、关联数组等。
3.5 集合
由一个或多个元素所构成的叫做集合(Set)。若x是集合A的元素,则记作x∈A。集合中的元素有三个特征:1.确定性(集合中的元素必须是确定的) 2.互异性(集合中的元素互不相同。例如:集合A={1,a},则a不能等于1) 3.无序性(集合中的元素没有先后之分。)
ES6已经有
Set
了,想了解的可以参考ECMAScript 6 入门:Set但基于理解Set特性,这里仍旧给出Set的一个实现:
3.3.2 双向链表
双向链表相比单项链表,每个节点多一个指针指向前一节点。
JavaScript实现
链表是一种物理存储单元上非连续、非顺序的存储结构,它既可以表示线性结构,也可以用于表示非线性结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。
3.3 链表
3.3.1 单向链表
链表的最简单形式是单向链表,它的每个节点包含2部分:数据+指向下一节点的指针。最后一个节点指向NULL。
JavaScript实现
3. 数据结构
首先补一些概念:
数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成。
Data_Structure=(D,R),其中D是数据元素的集合,R是该集合中所有元素之间的关系的有限集合。
数据结构具体指同一类数据元素中,各元素之间的相互关系,包括三个组成成分,数据的逻辑结构,数据的存储结构和数据运算结构。
数据的逻辑结构:指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,与存储位置无关。
逻辑结构包括:
数据的物理结构:指数据的逻辑结构在计算机存储空间的存放形式。
数据的物理结构是数据结构在计算机中的表示(又称映像),它包括数据元素的机内表示和关系的机内表示。由于具体实现的方法有顺序、链接、索引、散列等多种,所以,一种数据结构可表示成一种或多种存储结构。
数据元素的机内表示(映像方法): 用二进制位(bit)的位串表示数据元素。通常称这种位串为节点(node)。当数据元素有若干个数据项组成时,位串中与个数据项对应的子位串称为数据域(data field)。因此,节点是数据元素的机内表示(或机内映像)。
关系的机内表示(映像方法):数据元素之间的关系的机内表示可以分为顺序映像和非顺序映像,常用两种存储结构:顺序存储结构和链式存储结构。顺序映像借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系。非顺序映像借助指示元素存储位置的指针(pointer)来表示数据元素之间的逻辑关系。
3.1 栈
栈是只能在某一端插入和删除的特殊线性表。遵从后进先出(LIFO,Last In First Out)的原则。一般有以下方法:
JavaScript实现
事实上JS中数组具有
pop/push
等方法,已经可以完全表达栈的形式,以上代码也只是基于数组对封装。应用
如何得到数字的二进制形式?(
num.toString(2)
)正整数转换成二进制就是不断除二取余,然后倒序排列,高位补零。
3.2 队列
一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列是按照“先进先出”或“后进后出”的原则组织数据的。
Array的
push/shift
方法对应队列的入队和出对,其实也不用有所谓的JS队列实现(还是贴在下面了):快速排序
快速排序是 C.R.A.Hoare 于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
快速排序的步骤分为三步:
快速排序时间复杂度是 O(nlgn)。 快速排序是 不稳定 的。
排序(sort)
所谓排序,就是使一组记录按关键字递增(或递减)次序排列起来。
排序按策略可以分为五类:
插入排序(Insertion Sort):每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止。包括直接插入排序和希尔排序。
选择排序(Selection Sort):每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的序列的最后,直到全部记录排序完毕。有直接选择排序和堆排序。
交换排序:两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止。有冒泡排序和快速排序。
归并排序(Merge Sort):利用"归并"技术来进行排序。归并是指将若干个已排序的子文件合并成一个有序的文件。
分配排序:排序过程无须比较关键字,而是通过"分配"和"收集"过程来实现排序.它们的时间复杂度可达到线性阶:O(n)。
冒泡排序
冒泡排序是一种简单排序算法。它重复访问数组(最多n-1趟),每次比较相邻两个元素,顺序错误则交换,如果某趟没有任何交换,则证明数组已经有序。
冒泡排序时间复杂度:
o(n^2)
。 最好情况下,数组已经有序,只需要遍历一遍,o(n)
;最坏情况下,需要o(n^2)
。冒泡排序是 稳定 的。(直接)插入排序
插入排序把数组分为有序(开始为空)和无序两部分,遍历无序数组的每个元素,插入到有序数组的合适位置(也需要遍历有序数组)。
插入排序时间复杂度:
o(n^2)
。选择排序
选择排序是简单排序算法。把数组分为有序(开始为空)和无序两部分,遍历无序数组选择最小值,插入到有序数组尾部。
选择排序时间复杂度:
o(n^2)
。 选择排序是 不稳定 的,如[2, 2, 1]
的排序归并排序
归并排序基于分治法(divide and conquer )。归并排序首先把数组对半分,直到分成多个长度为1的原子数组(长度为1,必然有序),再把这些数组向上合并,保证每次合并后的数组都是有序的。
归并排序时间复杂度:
o(n log n)
。