栈
- 特点:先进后出(和用缸积酸菜一样)
- api:push pop length
栈vs数组
栈,逻辑结构。理论模型,不管如何实现,不受任何语言限制
数组,物理结构。真实的功能实现,受限于编程语言
实践:判断一个字符串是否括号匹配
遇到左括号{([就压栈(压栈也称入栈)
遇到右括号})]就判断栈顶,匹配则出栈
最后判断length是不是0
function matchs(left,right){
if(left==='['&&right===']'){return true}
if(left==='{'&&right==='}'){return true}
if(left==='('&&right===')'){return true}
return false
}
function matchBracket(str){
var length = str.length
if(length===0){return true}
var stack = []
var leftSysmbol="({["
var rightSysmbol = "]})"
for(var i=0;i<length;i++){
var s = str[i]
if(leftSysmbol.includes(s)){
stack.push(s)
}else if(rightSysmbol.includes(s)){
var top = stack[stack.length-1]
if(matchs(top,s)){
stack.pop()
}else{
return false
}
}
}
return stack.length===0
}
console.log(matchBracket('2(hi})'))
链表和数组
链表是一种物理结构(非逻辑结构),类似于数组
数组需要一段连续的内存区间,而链表是零散的
- 都是有序结构
- 链表:查询慢O(n),新增和删除快O(1)
- 数组:查询快O(1),新增和删除慢O(n)
链表节点的数据结构{value,next?,prev?}
//通过数组创建链表
function lb(arr) {
let length = arr.length
let curNode = { value: arr[length - 1] }
for (var i = length - 2; i >=0; i--) {
//i=2,arr[i]=300,curNode={value:300,next:{value:400}}
//i=1,arr[i]=200,curNode={value:200,next:{value:300,next:{value:400}}}
//i=0,arr[i]=100,curNode={value:100,next:{value:200,next:{value:300,next:{value:400}}}}
curNode = {
value:arr[i],
next:curNode}
}
return curNode
}
lb([100,200,300,400])
反转链表思路示意图
//反转链表
function revsetlb(listNode){
var prevNode = undefined
var curNode = undefined
var nextNode = listNode
// 以nextNode为主,遍历链表
while(nextNode){
if(curNode&&!prevNode){
delete curNode.next
}
if(curNode&&prevNode){
curNode.next = prevNode
}
prevNode = curNode
curNode = nextNode
nextNode = nextNode.next
}
curNode.next = prevNode
return curNode
}
var lb = lb([100,200,300,400])
console.log(revsetlb(lb))
React Fiber使用了链表
队列与链表
去找了个截图直接看了,原文更详细
如何使用链表实现队列
class MyQueue {
#head = null
#tail = null
#len = 0
// 入队
add(n) {
var newNode = {
value: n,
next: null
}
// 处理head
if (this.#head === null) {
this.#head = newNode
}
// 处理tail
const tailNode = this.#tail
if (tailNode) {
tailNode.next = newNode
}
this.#tail = newNode
// 记录长度
this.#len++
return this.#head
}
// 出队
dele() {
if (this.#head === null) {
return null
}
if (this.#len <= 0) { return null }
// 取值
var value = this.#head.value
// 处理head
this.#head = this.#head.next
// 记录长度
this.#len--
return value
}
get length() {
return this.#len
}
}
var q1 = new MyQueue()
q1.add(100)
q1.add(200)
q1.add(300)
console.log(q1.length)//3
q1.dele()
console.log(q1.length)//2
栈堆模型
js代码执行时,值类型变量,存储在栈,引用型变量,存储在堆
堆的特点
1、完全二叉树
2、最大堆:父节点>=子节点
3、最小堆:父节点<=子节点
4、堆在逻辑结构上是二叉树,在物理结构上是数组
数组:适合连续存储+节省空间
堆和平衡二叉树
1、堆查询比平衡二叉树慢
2、删除比平衡二叉树快,维持平衡快
3、整体复杂度都是在O(logn)级别的,即树的高度
堆的使用场景
1、特别适合“堆栈模型”
2、堆的数据,都是在栈中引用的,不需要从root遍历
3、堆恰巧是数组形式,根据栈的地址,可以O(1)找到目标