关于树的那些事

前言


来实现一个二叉搜索树

function BinarySearchTree () {
  // Node类用于保存树中每个节点
  var Node = function (key) {
    this.key = key;
    this.left = null
    this.right = null
  }
  var root = null
  //插入节点方法
  this.insert = function (key) {
    var newNode = new BinarySearchTree(key)
    if (root === null) {
      root = newNode
    } else {
      insertNode(root, newNode)
    }
  }
  var insertNode = function (oldNode, newNode) {
    if (newNode.key < oldNode.key) {
      if (!oldNode.left) {
        oldNode.left = newNode
      } else {
        insertNode(oldNode.left, newNode)
      }
    } else {
      if (!oldNode.right) {
        oldNode.right = newNode
      } else {
        insertNode(oldNode.right, newNode)
      }
    }
  }
  //中序遍历
  this.inOrderTraverse = function (root) {
    let res = []
    inOrderTraverseNode(root, res)
    return res
  }
  var inOrderTraverseNode = function (root, res) {
    if (!root) return
    inOrderTraverseNode(root.left, res)
    res.push(root.key)
    inOrderTraverseNode(root.right, res)
  }
  //先序遍历
  this.preOrderTraverse = function (root) {
    let res = [];
    preOrderTraverseNode(root, res)
    return res
  }
  var preOrderTraverseNode = function (root, res) {
    res.push(root.val, res)
    preOrderTraverseNode(root.left, res)
    preOrderTraverseNode(root.right, res)
  }
  //后序遍历
  this.postOrderTraverse = function (root) {
    let res = [];
    postOrderTraverseNode(root, res)
    return res
  }
  var postOrderTraverseNode = function (root, res) {
    if (!root) return
    postOrderTraverseNode(root.left, res)
    postOrderTraverseNode(root.right, res)
    res.push(root.key)
  }
  //最小值
  this.min = function () {
    return minNode(root)
  }
  var minNode = function (root) {
    if (!root) return null
    while (root.left) {
      root = root.left
    }
    return root.key
  }
  //最大值
  this.max = function () {
    return maxNode(root)
  }
  var maxNode = function (root) {
    if (!root) return null
    while (root.right) {
      root = root.right
    }
    return root.key
  }
  //查询是否有特定值
  this.search = function (node) {
    return searchNode(root, node)
  }
  var searchNode = function (root, node) {
    if (!root) return false
    while (root) {
      if (node.key < root.key) {
        searchNode(node.left, node)
      } else if (node.key > root.key) {
        searchNode(node.right, node)
      } else {
        return true
      }
    }
  }
}

递归实现二叉树的三种遍历

前序

function preTraverse (root) {
  if (!root) return null
  console.log(root)
  preTraverse(root.left)
  preTraverse(root.right)
}

中序

function inOrderTraverse (root) {
  if (!root) return null
  inOrderTraverse(root.left)
  console.log(root.val)
  inOrderTraverse(root.right)
}

后序

function postTraverse (root) {
  if (!root) return null
  postTraverse(root.left)
  postTraverse(root.right)
  console.log(root.val)
}

非递归实现二叉树的三种遍历

前序

function preNode (node) {
  let arr = [], res = []
  if (node) arr.push(node)
  while (arr.length) {
    let temp = arr.pop()
    res.push(temp.val)
    if (temp.right) arr.push(temp.right)
    if (temp.left) arr.push(temp.left)
  }
  return res
}

中序

function inNode (node) {
  let res = [], arr = []
  while (true) {
    while (node) {
      arr.push(node)
      node = node.left
    }
    if (!arr.length) break
    let temp = arr.pop()
    res.push(temp.val)
    node = temp.right
  }
  return res
}

后序

function postNode (node) {
  let arr = [], res = []
  if (node) arr.push(node)
  while (arr.length) {
    let temp = arr.pop()
    res.push(temp.val)
    if (temp.left) arr.push(temp.left)
    if (temp.right) arr.push(temp.right)
  }
  return res.reverse()
}

翻转二叉树_简单

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {TreeNode}
 */
var invertTree = function (root) {
    if (root) {
        [root.left, root.right] = [invertTree(root.right), invertTree(root.left)]
    }
    return root
};

根据前序和后序遍历构造二叉树_中等

返回与给定的前序和后序遍历匹配的任何二叉树。
pre 和 post 遍历中的值是不同的正整数。
示例: 输入:pre =[1,2,4,5,3,6,7], post = [4,5,2,6,7,3,1] 输出:[1,2,3,4,5,6,7]
提示: 1 <=pre.length == post.length <= 30 pre[] 和 post[] 都是 1, 2, …,
pre.length 的排列 每个输入保证至少有一个答案。如果有多个答案,可以返回其中一个。

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {number[]} pre
 * @param {number[]} post
 * @return {TreeNode}
 */
const constructFromPrePost = function (pre, post) {
    if (pre.length !== post.length || pre[0] !== post[post.length - 1]) return null
    if (pre.length === 1) return new TreeNode(pre[0])
    if (pre.length === 0) return null 
    // 初始化根节点,找到分割点
    const node = new TreeNode(pre[0])
    const index = post.indexOf(pre[1])
    // 构建左子树
    const lpre = pre.slice(1, index + 2)
    const lpost = post.slice(0, index + 1)
    node.left = constructFromPrePost(lpre, lpost)
    // 构建右子树
    const rpre = pre.slice(index + 2, pre.length)
    const rpost = post.slice(index + 1, pre.length - 1)
    node.right = constructFromPrePost(rpre, rpost)
    return node
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值