学习JavaScript数据结构

一、数组Array

典型应用之斐波那契数列:前2个项都为1,从第三项开始,每一项都等于前2项之和,求斐波那契数列的前20项。

第一反应是,用2个变量记录前两项,每次循环时更新这两个变量并打印出来:


以上做法的问题是这2个变量仅作为临时计算实用,结果的20个数并没能保存下来

用数组的方式:目的是要把这20个数利用数组arr保存下来,并去掉numPrev1 和 numPrev2这两个临时的变量,利用数组下标取值的方式计算出每一项:


数组的便利之处就在于【能只用一个变量存多个数据,不用创建很多变量来存每一项】,【利用数组下标能很方便地取各个位置上的值】,对保存和处理那些【在顺序上有规律的数据】来说非常实用。

二、栈Stack


后进先出,操作方向仅在栈顶

栈是一个遵循后进先出原则(LIFO)的有序集合,我们可以在数组的 任意位置 上操作元素,但栈限制了操作位置:只能在栈顶 进行存取操作。栈被用来在编程语言中保存变量、方法的调用顺序;保存访问过的路径,比如浏览器保存历史记录以回退到上一路径等。

1.创建一个基于数组的栈

2.创建一个基于对象的栈

将key为0的作为栈底,key越大越靠近栈顶

3.使用WeakMap保护私有属性

使用以上两种方法时,Stack的实例仍能访问并修改_items属性,用下划线命名只是一种约定,依赖于开发者的常识,我们希望能保护内部的元素,将_items作为私有属性,限制实例对它的访问:


WeakMap 的设计目的在于,有时我们想在某个对象上面存放一些数据,但是这会形成对于这个对象的引用,只要引用存在,垃圾回收 机制就不会释放对象占用的内存。 WeakMap 就是为了解决这个问题而诞生的,它的键名所引用的对象都是弱引用 ,只要所引用的对象的 其他引用 都被清除,垃圾回收机制就会释放该对象所占用的内存。也就是说,一旦不再需要,WeakMap 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用

4.利用栈实现进制转换

将10进制转换为2~36的任意进制,例如转换为二进制,将十进制的数除以2,每次将余数压入栈中,用商继续除以2,直到商为0.

5.校验圆括号是否平衡

三、队列(Queue)与双端队列(Deque:double-ended queue)

1.队列


先进先出

队列是遵循先进先出(FIFO,也成为先来先服务)原则的一组有序的项。它与栈非常类似,但栈 只在栈顶 进行存取,而队列是只能在 队尾存,队首取 :最新添加的元素必须排在末尾,最早被添加的元素最先得到服务。

常见的例子就是打印队列,先来先打印,后来先排队

经典问题之击鼓传花

围圈传递花,音乐停花在谁手里则谁淘汰,游戏里小朋友位置不变,传递花,用队列模拟就是相当于队列首部放一束花不懂,为危险位置,队列首部的小朋友不断跑到队列尾,音乐停谁在队首谁淘汰。

循环队列

2.双端队列

双端队列,允许我们同时从 两端进行存取

常见的例子是用双端队列存储最近的几次操作,最早的操作排在最前面,当需要撤销时从队尾弹出最近的一次操作,就像栈一样,后进的先出;当存储的操作数达到设定时,有最新操作进来就需要移除最早的操作,这个时候要从最前面移除,这时候就像队列一样,先进的先出,所以双端队列就像栈和队列相结合的一种数据结构。

双端队列是两端都可以存取,不过这个例子是在两端取,仅需要在一端存

判断字符串是否是回文(正读和反读相同)

用栈的思路是先反转再对比原字符串

用双端队列的思路是同时从两端取一个字符,对比是否相同

四、链表LinkedList

1. 链表LinkedList

链表能够确定一组(不是保存一组,链表本身只存第一个元素head的引用)有序的元素集合。不同于数组的是,链表中的元素在内存中并不是连续放置的,每个节点都存储元素本身和指向下一个节点的指针,元素顺序就是靠这些指向下一节点的指针来确定的。

实际这些节点并不是这样顺序排列的

在数组中插入或删除元素的成本很高,因为需要移动元素;

链表的好处就是添加或删除时不需要移动元素,只需要改变指针指向

当然,链表的缺点是额外保存了指针,而且因为元素在内存中不是连续放置的,在访问链表中间的元素时,只能从前往后迭代,无法像数组一样能直接通过位置找到元素;

当你需要添加和移除很多元素时,应该首选链表而非数组。

删除元素


2.双向链表

每个节点除了存储下个节点的指针外,还要存储上一个节点的指针

双向链表由于同时保存了前后两个节点的引用,可以进行前序和后序遍历,普通链表只能从前往后。由于可以进行双向遍历,当确定了要操作的元素位置时,可以根据位置的前后来决定遍历的方向,以减少迭代次数。

但是每个节点都要多分配一个指针存储前一个结点引用,增删时也需要维护前驱节点的指向。

3.循环链表

与链表的不同点在于,链表的最后一个元素的next不再指向undefined而是指向head节点;双向链表的head节点的prev指向最后一个节点。

循环链表的优点在于,从任意一个位置出发,都能遍历整个链表;普通链表则只能从指定位置遍历到尾部,或首部(如果是双向链表的话)。

循环链表中没有NULL指针,在遍历时也可以减少判断null的这个操作

五、集合Set

集合由一组无序且不相同的项组成。例如:N = {'A', 10, '哈', 4};


集合内的项无序且唯一

我们可以使用对象来模拟集合。将项作为对象的key以保证唯一性,增加项时则增加属性,删除项则删除该属性。

在进行集合运算时,可以用扩展运算符将集合转化为数组来操作:

1.并集:new Set([...setA,...setB])

2.交集:new Set([...setA].filter(i=>setB.has(i)))

3.差集:new Set([...setA].filter(i=>!setB.has(i)))

六、字典Map和散列表HashMap(page 145)

集合是以[值,值]的形式存储元素,字典以[键,值]的形式来存储元素。字典也称作映射、符号、关联数组。

在字典中,我们将key转化为字符串后,将value存在该字符串属性中。

在散列表(哈希表)中,我们【将key转化为字符串再使用每个字符的ASCII值转成一个数字】,将value存在该数字位置。这个转换函数是散列(hash)函数,散列函数的作用,就是给定一个键值,返回值在表中的位置。

1.处理散列表中的冲突

当不同的key有相同的散列值时,会有冲突,因为不同的值将对应同一个位置。

方法1:分离链接:为散列表的每一个位置创建一个链表,这样一个位置上相当于能存多个值了,不过存的时候需要既存值也存键,因为取的时候需要使用键来匹配链表中的值。

方法2:线性探查:当添加元素时发现位置被占了,就从此位置向后迭代,以找一个空闲的位置并插入。在查找值时,如果要查找的位置上有值,并且所存的key与要查找的key相同,则返回,否则向后查找哈希值为当前位置的元素并匹配key。当要删除某个值时,除了删除那个位置上的值以外,还要将其他冲突的元素移动至之前的位置 ,不产生空位置。


如果位置被占了就往后找一个空闲位置

七、树

一棵树包含一系列存在父子关系的节点,每个节点都有一个父节点和0/多个子节点。子树,由一个节点和它的后代构成;

节点的一个属性是深度,取决于祖先的数量;树的高度取决于所有节点深度的最大值

在树中,我们将节点称为【键】

1.二叉树与二叉搜索树(BST)

二叉树中的节点最多只能有2个子节点,二叉搜索树只允许在左侧节点存储比父节点小的值,右侧存储大的值。


二叉搜索树

2.树的遍历

2.1 中序遍历 (先访问左节点——再访问自身——再访问右节点)

以从最小到最大的顺序访问所有节点;


3,4,6,7,9,10,12,50
中序遍历

2.2 前序遍历(先访问自身——再访问左节点——再访问右节点)

前序遍历

2.3 后序遍历(先访问左节点——再访问右节点——再访问自身)

3,4,9,7,6,12,50,10


后序遍历

3.在树中搜索值

4.移除树中的节点

4.1 移除一个叶子节点

node4.left = null; node3 = null;

4.2 移除只有一个子节点的节点

node6.left = node4.left; node4 = null;

4.3 移除有两个子节点的节点

替换为右子树里最小的节点
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容