前言
整理一下,分享给所有和我一样想深入了解学习的人。
一、 关于数据结构
1、栈:是一种遵从后进先出(LIFO)原则的数据结构。虽然在我们前端中是没有栈这种数据结构的,但是我们有万能的数组,使用它可以模拟出栈,并且还能衍生出栈的操作方法,我们知道在es标准中数组有两个标准方法push和pop其实,他们就可以表示出栈和入栈的操作方法,
class Stack {
constructor() {
this.stack = []
// 栈的长度
this.size = 0
}
// 入栈
push(i) {
this.stack[this.size] = i
this.size++
}
// 出栈
pop() {
if (this.stack.length > 0) {
const last = this.stack[--this.size]
this.stack.length--
return last
}
}
// 查看栈顶元素
peek() {
return this.stack[this.size - 1];
}
// 栈是否为空
isEmpty() {
return stack.length === 0;
}
// 清空栈
clear() {
this.stack = []
}
// 查看栈元素
see(){
console.log(this.stack)
return this.stack
}
}
2、队列: 是一种遵从先进先出原则的数据结构。.最先进入的数据,只能先出去,他具有先进先出的特性。然而,在js的语法中同样的没有队列的数据结构,但是我们依然可以用数据来模拟队列的数据结构,由于队列是先进先出,我们首先需要模拟原生的入队push方法,再模拟原生的shift方法
class Queue {
constructor() {
// 创建一个队列
this.queue = []
// 队列长度
this.size = 0
}
// 入队列
push(i) {
this.queue[this.size] = i
this.size++
}
// 出队列
shift() {
if (this.queue.length === 0) {
return
}
const first = this.queue[0]
//将后面的赋值给前面的
for (let i = 0; i < this.queue.length - 1; i++) {
this.queue[i] = this.queue[i + 1]
}
this.queue.length--
return first
}
//获取队首
getFront() {
return this.queue[0];
}
//获取队尾
getRear() {
return this.queue[this.size - 1]
}
// 清空队列
clear() {
this.queue = []
}
// 查看队列元素
see() {
console.log(this.queue)
return this.queue
}
}
3、链表: 用链式存储的线性表统称为链表。其实他本质上就是一个多元素组成的列表,只不过他的元素存储不连续,需要再用next指针关联。分为单向链表和双向链表。
单向链表:它由节点组成,每个节点都包含下一个节点的指针,下图就是一个单链表,表头为空,表头的后继节点是"结点10"(数据为10的结点),"节点10"的后继结点是"节点20"(数据为10的结点)。
双向链表:和单链表一样,双链表也是由节点组成,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
4、字典:是一种以键-值对形式存储唯一数据的数据结构
关于算法:其实就是操作数据、解决程序问题的一组方法。分为以下:
时间维度:指执行当前算法所消耗的时间,通常用【时间复杂度】来描述。
空间维度:指执行当前短发需要占用多少内存空间,通常用【空间复杂度】来描述。