1数组
1.1方法列表
数组的常用方法如下:
- concat: 链接两个或者更多数据,并返回结果。
- every: 对数组中的每一项运行给定的函数,如果该函数对每一项都返回true,则返回true。
- filter: 对数组中的每一项运行给定函数,返回改函数会返回true的项组成的数组。
- forEach: 对数组中的每一项运行给定函数,这个方法没有返回值。
- join: 将所有的数组元素链接成一个字符串。
- indexOf: 返回第一个与给定参数相等的数组元素的索引,没有找到则返回-1。
- lastIndexOf: 返回在数组中搜索到的与给定参数相等的元素的索引里最大的值。
- map: 对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
- reverse: 颠倒数组中元素的顺序,原先第一个元素现在变成最后一个,同样原先的最后一个元素变成现在的第一个。
- slice: 传入索引值,将数组中对应索引范围内的元素作为新元素返回。
- some: 对数组中的每一项运行给定函数,如果任一项返回true,则返回true。
- sort: 按照字母顺序对数组排序,支持传入指定排序方法的函数作为参数。
- toString: 将数组作为字符串返回。
- valueOf: 和toString相似,将数组作为字符串返回。
1.2数组合并
concat方法可以向一个数组传递数组、对象或是元素。数组会按照该方法传入的参数顺序 连接指定数组。
1 | var zero = 0; |
1.3迭代器函数
reduce方法接收一个函数作为参数,这个函数有四个参数:previousValue、currentValue、index和array。这个函数会返回一个将被叠加到累加器的 值,reduce方法停止执行后会返回这个累加器。如果要对一个数组中的所有元素求和,这就很有用了。
1 | var isEven = function(x){ |
1.4排序
1 | var numbers = [1,2,3,4,5,6]; |
2栈
2.1栈的创建
对于一个栈,我们需要实现添加、删除元素、获取栈顶元素、已经是否为空,栈的长度、清除元素等几个基本操作。下面是基本定义。
1 | function Stack(){ |
2.2栈的基本使用
栈的基本操作。
1 | var stack = new Stack(); |
通过栈实现对正整数的二进制转换。
1 | function divideBy2(decNumber){ |
3 队列
3.1 队列的创建
队列是遵循FIFO(First In First Out,先进先出,也称为先来先服务)原则的一组有序的项。队列在尾部添加新元素,并从顶部移除元素。最新添加的元素必须排在队列的末尾。队列要实现的操作基本和栈一样,只不过栈是FILO(先进后出)。
1 | function Queue() { |
队列的基本使用
1 | var queue = new Queue(); |
3.2 优先队列
元素的添加和移除是基于优先级的。实现一个优先队列,有两种选项:设置优先级,然后在正确的位置添加元素;或者用入列操 作添加元素,然后按照优先级移除它们。
我们在这里实现的优先队列称为最小优先队列,因为优先级的值较小的元素被放置在队列最 前面(1代表更高的优先级)。最大优先队列则与之相反,把优先级的值较大的元素放置在队列最 前面。
3.2.1 优先队列的定义
我们在这里使用组合继承的方式继承自Queue队列。
1 | function PriorityQueue(){ |
3.2.1 优先队列的基本使用
1 | var pQueue = new PriorityQueue(); |
3.3 循环队列
循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
你的实现应该支持如下操作:1
2
3
4
5
6
7MyCircularQueue(k): 构造器,设置队列长度为 k 。
Front: 从队首获取元素。如果队列为空,返回 -1 。
Rear: 获取队尾元素。如果队列为空,返回 -1 。
enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
isEmpty(): 检查循环队列是否为空。
isFull(): 检查循环队列是否已满。
3.3.1 循环队列的定义
1 | export default class MyCircularQueue { |
3.3.1 循环队列的基本使用
1 | let queue = new MyCircularQueue(4) |
4 链表
数组的大小是固定的,从数组的起点或中间插入 或移除项的成本很高,因为需要移动元素(尽管我们已经学过的JavaScript的Array类方法可以帮 我们做这些事,但背后的情况同样是这样)。链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个 元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。
相对于传统的数组,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。然 而,链表需要使用指针,因此实现链表时需要额外注意。数组的另一个细节是可以直接访问任何 位置的任何元素,而要想访问链表中间的一个元素,需要从起点(表头)开始迭代列表直到找到 所需的元素
4.1 链表的创建
我们使用动态原型模式来创建一个链表。列表最后一个节点的下一个元素始终是null。
1 | function LinkedList(){ |
4.2 链表的基本使用
1 | var linkedList = new LinkedList(); |
4.3 双向链表的创建
链表有多种不同的类型,这一节介绍双向链表。双向链表和普通链表的区别在于,在链表中, 一个节点只有链向下一个节点的链接,而在双向链表中,链接是双向的:一个链向下一个元素, 另一个链向前一个元素。
双向链表和链表的区别就是有一个tail属性,所以必须重写insert、append、removeAt方法。每个节点对应的Node也多了一个prev属性。
1 | // 寄生组合式继承实现,详见javascript高级程序设计第七章 |
4.4 双向链表的基本使用
1 | var doublyList = new DoublyLinkedList(); |
4.5 循环链表
循环链表可以像链表一样只有单向引用,也可以像双向链表一样有双向引用。循环链表和链 表之间唯一的区别在于,最后一个元素指向下一个元素的指针(tail.next)不是引用null, 而是指向第一个元素(head)。双向循环链表有指向head元素的tail.next,和指向tail元素的head.prev。
代码后续补充~~~