中左右
function preorderTraversal( root ) {
let res = []
preOrder(root)
return res
function preOrder(node){
if(node === null) return
res.push(node.val)
preOrder(node.left)
preOrder(node.right)
}
}
左中右
function inorderTraversal( root ) {
let res = []
inorderTravese(root)
return res
function inorderTravese(node){
if(node === null) return null
inorderTravese(node.left)
res.push(node.val)
inorderTravese(node.right)
}
}
左右中
function postorderTraversal( root ) {
let res = []
postorderTraverse(root)
return res
function postorderTraverse(node){
if(node === null) return
postorderTraverse(node.left)
postorderTraverse(node.right)
res.push(node.val)
}
}
function levelOrder( root ) {
const res = [], queue = []
if(root === null) return null
queue.push(root)
while(queue.length){
let length = queue.length
const curLevel = []
while(length --){
let node = queue.shift()
curLevel.push(node.val)
node.left && queue.push(node.left)
node.right && queue.push(node.right)
}
res.push(curLevel)
}
return res
}
二叉树的最大深度
输入:{1,2}
返回值:2
方法:利用层序,有几层深度就是多少
function maxDepth( root ) {
let res = 0
if(root === null) return res
const queue = []
queue.push(root)
while(queue.length){
let len = queue.length
while(len --){
let node = queue.shift()
node.left && queue.push(node.left)
node.right && queue.push(node.right)
}
res ++
}
return res
}
// 递归方法
function maxDepth( root ) {
// write code here
if(root === null) return 0
let max = 0
if(root.left){
max = Math.max(max, maxDepth(root.left))
}
if(root.right){
max = Math.max(max, maxDepth(root.right))
}
return max + 1
}
二叉树中和为某一值的路径
输入:{5,4,8,1,11,#,9,#,#,2,7},22
返回值:true
方法:递归
function hasPathSum(root, sum) {
// write code here
// 空树
if (root === null) return false
function dfs(node, sum) {
if (node === null) return false
// 已经遍历到叶子节点
if (node.left === null && node.right === null && node.val === sum) {
return true
}
return dfs(node.left, sum - node.val) || dfs(node.right, sum - node.val)
}
return dfs(root, sum)
}
二叉搜索树与双向链表
方法:利用中序遍历
function Convert(pRootOfTree) {
// head:头节点
// pre:记录上一节点
let head = null, pre = null
// 中序遍历
function traversal(node) {
if (node === null) {
return
}
traversal(node.left)
// 处理当前节点
// 如果是前序遍历的第一个节点,head始终指向该节点
if (node.left === null && head === null) {
head = node
pre = node
} else {
// 前一节点的右指针指向当前节点
// 当前节点的左指针指向前一节点
// 更新pre
pre.right = node
node.left = pre
pre = node
}
traversal(node.right)
}
traversal(pRootOfTree)
return head
}
对称二叉树
function isSymmetrical(pRoot) {
function isSym(left, right) {
// 没有子节点
if (left === null && right === null) {
return true
}
// 只有一个节点为空
if (left === null || right === null) {
return false
}
// 数值不相等
if (left.val !== right.val) {
return false
}
return isSym(left.left, right.right) && isSym(left.right, right.left)
}
if (pRoot === null) {
return true
}
return isSym(pRoot.left, pRoot.right)
}
合并二叉树
都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。
function mergeTrees( t1 , t2 ) {
if(t1 === null) return t2
if(t2 === null) return t1
t1.val = t1.val + t2.val
t1.left = mergeTrees(t1.left, t2.left)
t1.right = mergeTrees(t1.right, t2.right)
return t1
}
二叉树的镜像
function Mirror( pRoot ) {
if(pRoot === null){
return null
}
let tmp = pRoot.left
pRoot.left = pRoot.right
pRoot.right = tmp
Mirror(pRoot.left)
Mirror(pRoot.right)
return pRoot
}
判断是不是二叉搜索树
方法:中序遍历,然后判断是否是递增
function isValidBST(root) {
// 中序遍历,判断是否递增
function travel(node) {
if (node) {
travel(node.left)
arr.push(node.val)
travel(node.right)
}
}
let arr = []
travel(root)
for (let i = 1; i < arr.length; i++) {
if (arr[i] <= arr[i - 1]) {
return false
}
}
return true
}
判断是不是完全二叉树
方法:利用层序遍历,如果是完全二叉树,直到最后才会遇到null
function isCompleteTree( root ) {
let queue = []
queue.push(root)
// 标记是否遇到空节点
let flag =false
while(queue.length){
const node = queue.shift()
// 遇到空节点则标记成true
if(node === null) {
flag = true
} else {
// 当前节点不是空节点,但flag是true,则说明不是完全二叉树
if(flag === true) {
return false
}
queue.push(node.left)
queue.push(node.right)
}
}
return true
}
判断是不是平衡二叉树
方法:求出左右子树的最大深度,绝对值小于等于1。特别注意:左右子树也要满足平衡二叉树
function IsBalanced_Solution(pRoot) {
if (pRoot === null) return true
// 求最大深度
function maxDeep(node) {
let max = 0
if (node.left) {
max = Math.max(max, maxDeep(node.left))
}
if (node.right) {
max = Math.max(max, maxDeep(node.right))
}
return max + 1
}
// 求左右子树的最大深度
let leftDeep = 0, rightDeep = 0
if (pRoot.left) {
leftDeep = maxDeep(pRoot.left)
}
if (pRoot.right) {
rightDeep = maxDeep(pRoot.right)
}
// 左右子树的最大深度差小于等于1 且 左右子树都满足平衡二叉树
return Math.abs(leftDeep - rightDeep) <= 1
&& IsBalanced_Solution(pRoot.left)
&& IsBalanced_Solution(pRoot.right)
}
二叉树的最近公共祖先
方法:如果left和right的返回值都不为空,则返回root;否则返回不为空的那个。
function TreeNode(val) {
this.val = val;
this.left = this.right = null;
}
var lowestCommonAncestor1 = function(root, p, q){
function travelTree(node, p, q){
if(node === null || node === p || node === q){
return node
}
let left = travelTree(node.left, p, q)
let right = travelTree(node.right, p, q)
if(left !== null && right !== null){
return node
}
if(left === null){
return right
}
return left
}
return travelTree(root, p, q)
}
二叉搜索树的最近公共祖先
方法:如果val大于p和q的val,则从节点的左子树开始找
var ancestor = function(root, p, q){
while (root) {
if(root.val > p.val && root.val > q.val){
root = root.left
}else if(root.val < q.val && root.val < p.val){
root = root.right
}else{
return root
}
}
return null
}
从前序与中序遍历序列构造二叉树
var buildTreefromPreInorder = function(preorder, inorder){
if(!preorder.length) return null
let root = new TreeNode(preorder[0])
let mid = inorder.findIndex(number => number === root.val)
root.left = buildTreefromPreInorder(preorder.slice(1, mid + 1), inorder.slice(0, mid))
root.right = buildTreefromPreInorder(preorder.slice(mid + 1, preorder.length), inorder.slice(mid + 1, inorder.length))
}
106. 从中序与后序遍历序列构造二叉树
// 中序+后序
var buildTreefromPostInorder = function(inorder, postorder){
if(!postorder.length) return null
// 构建根节点
let root = new TreeNode(postorder[postorder.length - 1])
// 寻找分割点
let index = inorder.findIndex(number => number === root.val)
root.left = buildTreefromPostInorder(inorder.slice(0,index), postorder.slice(0,index))
root.right = buildTreefromPostInorder(inorder.slice(index + 1, inorder.length), postorder.slice(index, postorder.length - 1))
return root
}