栈
一个后进先出的数据结构
数组模拟栈
附带相关功能代码
const stack = [];
//入栈
stack.push(1);
//出栈
const popStack = stack.pop();
队列
一个先进先出的数据结构
代码模拟实现
附带相关功能代码
const queue = [];
//入栈
queue.push(1);
//出栈
queue.shift();
链表
- 多个元素组成的列表
- 元素存储不连续,用next指针链接在一起
代码模拟实现
附带相关功能代码
const a = {
val:“a”
}
const b = {
val:"b"
}
const c = {
val:"c"
}
a.next = b;
b.next = c;
//遍历链表
let pointer = a;
while(pointer){
console.log(pointer.val);
pointer = pointer.next;
}
//出入链表值
const e = {
val:"e"
}
b.next = e;
e.next = c;
//删除
b.next = c;
集合
一种无序且唯一的结构,js中的Set可模拟实现
结构图片想不出来了~~~~
代码模拟实现
附带相关功能代码
//去重
const arr = [1,1,2,2];
const arr2 = [...new Set(arr)];
//判断元素是否在集合中
const set = new Set(arr);
const has = set.has(1);
//求交集
const set2 = new Set([2,3]);
const set3 = new Set([...set].filter(item=>set2.has(item)));
字典
与集合类似,同样是存储唯一值的数据结构,但是,它是以键值对来进行存储的,例如js中的Map
树
一种分层数据的抽象模型,应用中有树的广度优先遍历和深度优先遍历,另有二叉树的先序遍历,中序遍历和后序遍历
树的深度与广度优先遍历
深度遍历
尽可能深入地搜索树的分支
代码模拟实现
const tree = {
val:"a",
children:[
{
val:"b",
children:[
{
val:"e",
children:[]
},
{
val:"f",
children:[]
}
]
},
{
val:"c",
children:[
{
val:"g",
children:[]
}
]
}
],
}
//遍历
const dfs = (root)=>{
console.log(root.val);
root.children.forEach(dfs);
}
dfs(tree);
广度优先遍历
先遍历离根节点最近的节点
代码模拟实现
const tree = {
val:"a",
children:[
{
val:"b",
children:[
{
val:"e",
children:[]
},
{
val:"f",
children:[]
}
]
},
{
val:"c",
children:[
{
val:"g",
children:[]
}
]
}
],
}
const bfs = (root)=>{
const q = [root];
while(q.lenght>0){
const n = q.shift();
console.log(n.val);
n.children.forEach(child=>{
q.push(child);
})
}
}
bfs(tree);
二叉树
- 树中的子节点最多只能有2个节点
- 在js里,通常用object来模拟实现
先序遍历
- 先访问根节点
- 左节点先序遍历
- 右节点先序遍历
先序遍历,根节点->左子树->右子树进行遍历
代码模拟实现
const tree = {
val: 1,
left: {
val: 2,
left: {
val: 4,
left: null,
right: null,
},
right: {
val: 5,
left: null,
right: null,
},
},
right: {
val: 3,
left: {
val: 6,
left: null,
right: null,
},
right: {
val: 7,
left: null,
right: null,
},
},
};
const preorder = (root)=>{
if(!root) return;
console.log(root.val);
preorder(root.left);
preorder(root.right);
}
preorder(tree);
中序遍历
- 对根节点的左子树进行中序遍历
- 访问根节点
- 对根节点的右子树进行中序遍历
中序遍历,即左子树->根节点->右子树进行遍历
代码模拟实现
const tree = {
val: 1,
left: {
val: 2,
left: {
val: 4,
left: null,
right: null,
},
right: {
val: 5,
left: null,
right: null,
},
},
right: {
val: 3,
left: {
val: 6,
left: null,
right: null,
},
right: {
val: 7,
left: null,
right: null,
},
},
};
const inorder = (root)=>{
if(!root) return;
inorder(root.left);
console.log(root.val);
inorder(root.right);
}
inorder(tree);
后序遍历
- 对根节点的左子树进行后序遍历
- 对根节点的右子树进行后序遍历
- 访问根节点
后序遍历,即左子树->右子树->根节点的遍历方式
代码模拟实现
const tree = {
val: 1,
left: {
val: 2,
left: {
val: 4,
left: null,
right: null,
},
right: {
val: 5,
left: null,
right: null,
},
},
right: {
val: 3,
left: {
val: 6,
left: null,
right: null,
},
right: {
val: 7,
left: null,
right: null,
},
},
};
const postorder = (root)=>{
if(!root) return;
postorder(root.left);
postorder(root.right);
console.log(root.val);
}
postorder(tree);
图
图,一种网络结构的抽象模型,即一组由边连接的节点
图可以表示任何二元关系,例如航班
二元关系指的是一条边连了两个节点关系
其中,应用中有深度优先遍历和广度优先遍历
深度优先遍历
- 访问根节点
- 对根节点的没访问过的相邻节点挨个进行深度优先遍历
相关代码实现
const graph = {
0: [1, 2],
1: [2],
2: [0, 3],
3: [3]
};
const visited = new Set();
const dfs = (d)=>{
console.log(d);
visited.add(d);
graph[d].forEach((g)=>{
if(!visited.has(g)){
dfs(g);
}
})
}
dfs(2);
广度优先遍历
- 新建一个队列且根节点入队
- 把队头出队并访问
- 把对头的没访问过的相邻节点入队
- 重复2,3步直到队列为空
相关代码实现
const graph = {
0: [1, 2],
1: [2],
2: [0, 3],
3: [3]
};
const visited = new Set();
visited.add(2);
const arr = [2];
while(arr.length){
const arrShift = arr.shift();
console.log(arrShift);
graph[arrShift].forEach((g)=>{
if( !visited.has(g) ){
arr.push(g);
visited.add(g);
}
})
}
堆
堆,一种特殊的完全二叉树
所有的节点都大于等于即最大堆,反之最小堆
js中通常用数组来模拟堆
左侧子节点的位置是2 * index + 1;
右侧子节点的位置是2 * index + 2;
父节点位置是(index - 1) / 2;
相关代码,最小堆类代码实现
class MinHeap{
constructor(){
this.heap = [];
}
swap(i1,i2){
[this.heap[i1],this.heap[i2]] = [this.heap[i2],this.heap[i1]];
}
getParentIndex(i){
return (i - 1) >> 1;
}
shiftUp(index){
if(index == 0) return;
const parentIndex = this.getParentIndex(index);
if( this.heap[parentIndex] > this.heap[index] ){
this.swap(parentIndex,index);
this.shiftUp([parentIndex]);
}
}
insert(value){
this.heap.push(value);
this.shiftUp(this.heap.length - 1);
}
}