前端中的数据结构与算法(一)

141 阅读2分钟

前言

本文章为本人学习数据结构与一些算法时做的记录文章,收录在《前端中的数据结构与算法》中

栈(Stack)

栈是后进先出的线性表,在js中,我们可以看做一个数组,进栈(添加元素)的方法为push(),而出栈(移除元素)的方法为pop()

例如:

const stack = [];
//入栈
stack.push(1);//[1]
stack.push(2);//[1,2]
stack.push(3);//[1,2,3]
//出栈
stack.pop();//[1,2]
stack.pop();//[1]
stack.pop();//[]

队列(Queue)

队列是先进先出的线性表,在js中,我们同样也可以把队列看做一个数组,入队(添加元素)的方法为push(),而出队(移除元素)的方法为shift()

例如:

const queue = [];
//入队
queue.push(1);//[1]
queue.push(2);//[1,2]
queue.push(3);//[1,2,3]
//出对
queue.shift();//[2,3]
queue.shift();//[3]
queue.shift();//[]

链表(ListNode)

在js中,链表是一种类数组对象。关于数组,它的内存空间是连续的,而链表是分散的。所以链表需要前驱后继来进行关联。其中,链表的数据单位叫结点

注意,为了确保起点结点是能抵达的,我们有时还会设定一个head指针来专门指向链表的开始位置。

我们可以使用对象来模拟它:

const node = {
    value:1,
    next:{
        value:2,
        next:{
            //...
        }
    }
}

书写构造函数

function ListNode(value){
  this.value = value
  this.next = null
}

const node = new ListNode(1)
node.next = new ListNode(2)
console.log(node);//ListNode { value: 1, next: ListNode { value: 2, next: null } }

链表结点的添加

//如果节点不存在,则创建该节点
const node3 = new ListNode(3)
//将node3的后继指向node2(node1的后继)
node3.next = node1.next
//将node1的后继指向node3
node1.next = node3

链表结点的删除

(node1-node3-node2=>node1-node2):

//找到node1当前的后继(node3)
const target = node1.next
//将此时的node1的后继改为node3的后继(node2)
node1.next = target.next

此时的node3便成为一个无法到达的节点了,所以会被js的垃圾回收自动回收。

链表与数组比较

链表读取数据的时间复杂度为O(n),因为需要从起始结点遍历到查询的结点为止,数组为O(1)。但相对数组,链表对数据的添加删除更加便捷。