数据结构简记

141 阅读2分钟

口语化,方便记忆

队列queue

先进先出的数据结构

可用数组的pushshift方法实现

push方法将元素加入到数组末尾

shift方法将第一个元素删除

栈Stack

后进先出的数据结构

可用数组的pushpop方法实现

pop方法将最后一个元素删除

js函数调用栈就是一个栈

比如:

function f1(){let a=1 ;return a+f2()}
function f2(){let b=2;return b+f3()}
function f3(){let c=3;return c}
f1()

执行过程是

  1. 函数定义先忽略,直到f1()调用
  2. f1()添加进调用栈
  • 调用栈
    • f1()
  1. 执行f1()中的代码,碰到f2(),将f2()添加进调用栈
  • 调用栈
    • f2()
    • f1()
  1. 执行f2()中的代码,碰到f3(),将f3()添加进调用栈
  • 调用栈
    • f3()
    • f2()
    • f1()
  1. 执行f3()中的代码,没有函数,直接执行完毕,f3()弹栈
  • 调用栈
    • f2()
    • f1()
  1. 接着继续执行f2()中的代码,f3返回了3,f2中的代码执行完毕,f2弹栈
  • 调用栈
    • f1()
  1. 继续执行f1()中的代码,f2返回了5,f1中代码执行完毕,f1()弹栈,执行结束

链表

一个接着一个数据结构

原型链的实现就是链表,实例上保存着指向原型的地址,实例的原型上又存在原型的地址,形成一个链表结构

要删除一个节点,只要把上一个节点的next指向下一个节点就行

链表的增删改查

const createList=value=>{
  return createNode(value)
}

const appendList=(list,value)=>{
  const node = createNode(value)
  while (list.next) {
    list=list.next
  }
  list.next=node
  return node
}

const removeFromList = (list, node) => {
  let previous=node
  while (list !== node&&list!==null) {
    //这里的p始终是上一个节点
    previous = list
    //list最终会是要删的那个节点
    list=list.next
  }
  if (list === null) {
    return
  } else if (list === previous) {
    previous = list.next
    return previous
  } else {
    previous.next = list.next
    return list
  }
}
const createNode=value=>{
  return{
    data:value,
    next:null
  }
}
const travelList = (list,fn) => {
  while (list!==null) {
    fn(list)
    list=list.next
  }
}
const list=createList(10)
const node1=appendList(list,20)
const node2=appendList(list,30)
console.log(list)
travelList(list, node => {
  console.log(node.data)
})
let x=list
const newList=removeFromList(list, x)
console.log(newList)

哈希表

键值对

  1. 不做任何优化,hash['xxx']需要遍历所有key,O(n)
  2. 对key排序,使用二分查找,O(log2 n)
  3. 用字符串对应的ACSII数字做索引,O(1)
  4. 对索引做除法取余数,O(1),冲突就顺延

相比链表是一个接一个,树是一个接多个

如网页中的节点,就是一棵树

实现一下增删改查

let createTree = (value) => {
  return {
    data: value,
    children: null,
    parent:null
  }
}

const addChild = (node,value) => {
  const newNode = {
    data: value,
    children: null,
    parent:node
  }
  node.children = node.children || []
  node.children.push(newNode)
  return newNode
}
const travel = (tree, fn) => {
  fn(tree)
  if (!tree.children) {
    return
  }
  for (let i = 0; i < tree.children.length; i++){
    travel(tree.children[i],fn)
  }
}
const removeNode = (tree, node) => {
  const siblings = node.parent.children
  let index = 0
  for (let i = 1; i < siblings.length; i++){
    if (siblings[i] === node) {
      index=i
    }
  }
  siblings.splice(index,1)
}
const tree = createTree(10)
const node2 = addChild(tree, 20)
addChild(tree, 30)
addChild(tree, 40)
const node5=addChild(tree, 50)
addChild(node2, 201)
addChild(node2, 202)
addChild(node2,203)
console.log(tree)

travel(tree, node => {
  console.log(node.data)
})

removeNode(tree, node5)
console.log(tree)