几个二叉树和队列的题目

前言

出不了门,在家做题

二叉树的遍历

分别用前中后三种遍历方式,先递归再循环,首先第一个是数的定义。

function TreeNode = (val) => {
  this.val = val;
  this.left = null;
  this.right = null;
}

前序

const preOrder = (root) => {
  if(!root) return []
  return [root.val, ...preOrder(root.left), ...preOrder(root.right)]
}
const preOrder = (root) => {
  if(!root) return []
  let stack = [], res = []
  stack.push(root)
  while(stack.length) {
    let node = stack.pop()
    res.push(node.val)
    if(node.right) stack.push(node.right)
    if(node.left) stack.push(node.left)
  }
  return res
}

中序

const innerOrder = (root) => {
  if(!root) return []
  return [...innerOrder(root.left), root.val, ...innerOrder(root.right)]
}
const innerOrder = (root) => {
  if(!root) return []
  let stack = [], res = [], p = root
  while(stack.length || p) {
    while(p) {
      stack.push(p)
      p = p.left
    }
    let node = stack.pop()
    res.push(node.val)
    p = node.right
  }
  return res
}

后序

function backOrder = (root) => {
  if(!root) return []
  return [...backOrder(root.left),  ...backOrder(root.right),root.val]
}
function backOrder = root => {
  if(!root) return []
  let stack = [], res= [], dic = new Set(),p = root
  while(stack.length || p) {
    while(p) {
      stack.push(p)
      p = p.left
    }
    let node = stack.slice(-1)[0]
    if(node.right && !dic.has(node.right)) {
      p = node.right
      dic.add(node.right)
    } else {
      res.push(node.val)
      stack.pop()
    }
  }
  return res
}

二叉树的最大(最小)深度

换个方式,先用递归求两个深度,在使用循环

function maxDepth(root) {
  if(!root) return 0
  return Math.max(maxDepth(root.left)+1, maxDepth(root.right)+1)
}
function minDepth(root) {
  if(!root) return 0
  if(root.left && root.right) {
    return Math.min(minDepth(root.left), minDepth(root.right))+1
  } else {
    return Math.max(minDepth(root.left), minDepth(root.right))+1
  }
}

接着使用DFS循环

function maxDepth(root) {
  if(!root) return 0
  let queue = [root], level = 0;
  while(queue.length) {
    let size = queue.length
    while(size--) {
      let front = queue.shift()
      if(front.left) queue.push(front.left)
      if(front.right) queue.push(front.right)
    }
    level++
  }
  return level
}
function minDepth(root) {
  if(!root) return 0
  let queue = [root], level = 0
  while(queue.length) {
    let size = queue.length
    while(size--) {
      let front = queue.shift()
      if(!front.left&& !front.right) return level+=1
      if(front.left) queue.push(front.left)
      if(front.right) queue.push(front.right)
    }
    level++
  }
  return level
}

二叉树的最近公共祖先

还是循环和递归

function closedAns(root, p, q) {
  if(!root || root===p ||root===q) return root
  let set = new Set(), map = new Map(), queue = [root]
  while(queue.length){
    let size = queue.length
    while(size--) {
      let front = queue.shift()
      if(front.left) {
        queue.push(front.left)
        map.set(front.left, front)
      }
      if(front.right) {
        queue.push(front.right)
        map.set(front.right, front)
      }
    }
  }
  while(q) {
    set.add(q)
    q = map.get(q)
  }
  while(p){
    if(set.has(p)) return p
    p = map.get(p)
  }
}
function closedAns(root, p, q) {
  if(!root || root===q || root===p) return root
  let left = closedAns(root.left, p, q)
  let right = closeAns(root.right, p, q)
  if(!left) return right
  else if(!right) return left
  return root
}

二叉搜索树的最近公共祖先

由于二叉搜索树的特性,我们可以使用这种递归:

function searchClosedAns(root, p, q) {
  if(!root || root===q || root===p) return root
  if(root.val> Math.max(q.val, p.val)) return searchClosedAns(root.left, p, q)
  if(root.val < Math.min(q.val, p.val)) return searchClosedAns(root.right, p,q)
  return root
}

当然也有循环的方式

function searchClosedAns(root, p, q) {
  while(root) {
    if(root.val>Math.max(q.val, p.val)) root = root.left
    else if(root.val<Math.min(q.val, p.val)) root = root.right
    else return root
  }
}
发布了362 篇原创文章 · 获赞 352 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43870742/article/details/104160765