JS中数据结构

栈(Stack)

是一种遵从后进先出(LIFO)原则的有序集合。新添加的或待删除的元素都保存在栈的 同一端,称作栈顶,另一端就叫栈底。在栈里,新元素都靠近栈顶,旧元素都接近栈底。

实现栈结构

const Stack = (() => {
  const wm = new WeakMap()
  class Stack {
    constructor() {
      wm.set(this, [])
      this.top = 0
    }

    push(...nums) {
      let list = wm.get(this)
      nums.forEach(item => {
        list[this.top++] = item
      })
    }

    pop() {
      let list = wm.get(this)
      let last = list[--this.top]
      list.length = this.top
      return last
    }

    peek() {
      let list = wm.get(this)
      return list[this.top - 1]
    }

    clear() {
      let list = wm.get(this)
      list.length = 0
    }

    size() {
      return this.top
    }

    output() {
      return wm.get(this)
    }

    isEmpty() {
      return wm.get(this).length === 0
    }
  }
  return Stack
})()

let s = new Stack()

s.push(1, 2, 3, 4, 5)
console.log(s.output()) // [ 1, 2, 3, 4, 5 ]
复制代码

利用栈十进制转化为其他进制

function divideBy2(decNumber, base = 2) {
  let remStack = new Stack()
  let rem
  let binaryString = ''
  let digits = '0123456789ABCDEF'
  while (decNumber > 0) {
    rem = Math.floor(decNumber % base)
    remStack.push(rem)
    decNumber = Math.floor(decNumber / base)
  }
  while (!remStack.isEmpty()) {
    binaryString += digits[remStack.pop()].toString()
  }
  return binaryString
}

// 将十进制转换成其他进制
let num = 100345
num.toString(2) // "11000011111111001"
num.toString(8) // "303771"

console.log(divideBy2(num, 2)) // "11000011111111001"
console.log(divideBy2(num, 8)) // "303771"
复制代码

二叉树

二叉搜索树

class Node {
  constructor(key) {
    this.key = key
    this.right = this.left = null
  }
}

class BinarySearchTree {
  constructor(list = []) {
    this.root = null
    if (list.length) {
      this.root = new Node(list.shift())
      list.forEach(item => this.insert(item))
    }
  }

  insert(item) {
    let newNode = new Node(item)
    if (this.root == null) {
      this.root = newNode
    } else {
      this._insertNode(this.root, newNode)
    }
  }
  _insertNode(node, newNode) {
    if (newNode.key < node.key) {
      if (node.left === null) {
        node.left = newNode
      } else {
        this._insertNode(node.left, newNode)
      }
    } else {
      if (node.right === null) {
        node.right = newNode
      } else {
        this._insertNode(node.right, newNode)
      }
    }
  }

  // 先序遍历 根 左 右
  preOrderTraverseNode(node, callback) {
    if (node instanceof Node) {
      callback(node.key)
      this.preOrderTraverseNode(node.left, callback)
      this.preOrderTraverseNode(node.right, callback)
    }
  }

  // 中序遍历 左 根 右
  inOrderTraverseNode(node, callback) {
    if (node instanceof Node) {
      this.inOrderTraverseNode(node.left, callback)
      callback(node.key)
      this.inOrderTraverseNode(node.right, callback)
    }
  }

  // 后序遍历 左 右 根
  postOrderTraverseNode(node, callback) {
    if (node instanceof Node) {
      this.postOrderTraverseNode(node.left, callback)
      this.postOrderTraverseNode(node.right, callback)
      callback(node.key)
    }
  }

  // 搜索最小值
  min() {
    return this._minNode(this.root)
  }

  _minNode(node) {
    while (node instanceof Node && node.left) {
      node = node.left
    }
    return node ? node.key : null
  }

  // 搜索最大值
  max() {
    return this._maxNode(this.root)
  }

  _maxNode(node) {
    while (node instanceof Node && node.right) {
      node = node.right
    }
    return node ? node.key : null
  }

  // 搜索特定值
  search(key) {
    return this._searchNode(this.root, key)
  }

  _searchNode(node, key) {
    if (node instanceof Node) {
      if (node.key === key) {
        return true
      }

      if (key < node.key) {
        return this._searchNode(node.left, key)
      } else {
        return this._searchNode(node.right, key)
      }
    }

    return false
  }

  findMinNode(node) {
    while (node && node.left !== null) {
      node = node.left
    }
    return node
  }
  // 删除指定值
  remove(key) {
    return this._removeNode(this.root, key)
  }
  _removeNode(node, key) {
    if (node === null) {
      return null
    }
    if (key < node.key) {
      // 根据当前node 去它的左子节点继续查找
      node.left = this._removeNode(node.left, key)
      return node
    } else if (key > node.key) {
      // 根据当前node 去它的右子节点继续查找
      node.right = this._removeNode(node.right, key)
      return node
    } else {
      // 找到了 删除节点

      // 情况1:删除节点 没有子节点的情况下 直接删除
      if (node.left === null && node.right === null) {
        node = null
        return node
      }

      // 情况2:删除节点 只有一个子节点
      if (node.left === null) {
        node = node.right
        return node
      } else if (node.right === null) {
        node = node.left
        return node
      }

      // 情况3:删除节点 有两个节点
      // console.log(node)
      // 查找右边最小节点
      let min = this.findMinNode(node.right)
      node.key = min.key
      node.right = this._removeNode(node.right, min.key)
      return node
    }
  }
}

const list = [10, 6, 20, 8, 12, 5, 22]
const tree = new BinarySearchTree(list)
tree.insert(17)
// console.log(tree)

tree.remove(20)
// console.log(tree.min())
// console.log(tree.max())

// 先序遍历
// tree.preOrderTraverseNode(tree.root, key => {
//   console.log(key) // 10 6 5 8 20 12 17 22
// })

// 中序遍历
// tree.inOrderTraverseNode(tree.root, key => {
//   console.log(key) // 5 6 10 12 17 20 22
// })

// 后序遍历
// tree.postOrderTraverseNode(tree.root, key => {
//   console.log(key) // 5 8 6 17 12 22 20 10
// })

复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值