二叉树的一些解题思路与模板

完全二叉树

概念

完全二叉树是可以没有右子树,不能没有左子树。

解题思路

判断是否是一颗完全二叉树:使用层序遍历方法,如果发现有右无左或者发现第一个左右节点不双全,则后面节点必须都为叶子节点,否则不是完全二叉树。

二叉搜索树(BST)

概念

二叉搜索树(BST):每个节点的左子树数据都小于该节点数据,右子树大于该节点数据

解题思路

判断是否是一颗二叉搜索树:中序遍历,该数组一定为升序数组。

满二叉树

概念

满二叉树:除叶子结点,所有结点都有左右子树。

解题思路

判断是否为满二叉树:先统计该树的最大深度L,再统计该树的节点数N,满足N = 2^L - 1则为满二叉树

平衡二叉树

概念

平衡二叉树:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

解题思路

以剑指offer的JZ79 判断是不是平衡二叉树为例。根据概念,先写出求解深度的一个函数,然后写判断条件:1、空树也是平衡二叉树,返回true。2、左右两个子树的高度差的绝对值不超过1。最后因为是要每个子树都是平衡二叉树而不是只从根节点,所以也要递归IsBalanced_Solution该方法。

/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */
function IsBalanced_Solution(pRoot)
{
    // write code here
    function depth(r){
        if(r === null){
            return 0
        }
        return Math.max(depth(r.left),depth(r.right)) + 1
    }
    if(pRoot === null){
        return true
    }
    return Math.abs(depth(pRoot.left) - depth(pRoot.right)) <= 1 && IsBalanced_Solution(pRoot.left) && IsBalanced_Solution(pRoot.right)
}
module.exports = {
    IsBalanced_Solution : IsBalanced_Solution
};

对称二叉树

概念

对称二叉树:以根节点为对称轴,左右子树成轴对称的树。

解题思路

以剑指offer的JZ28 对称的二叉树为例。使用层序遍历的方法进行判断。先准备一个队列,将根节点入队两次(因为每次要两两进行比较,出队的时候要出队两次),每次都要出队两次,判断:1、是否都为空,是的话跳过该次循环。2、判断出队的两个是否出现有一个不存在(因为是对称二叉树)。3、判断两个值是否相同,不相同直接返回false。然后入队顺序为queue.push(a.left); queue.push(b.right); queue.push(a.right); queue.push(b.left);(因为出队后,需要两两比较它的值)

/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */
function isSymmetrical(pRoot)
{
    // write code here
    if(pRoot === null){
        return true
    }
    let queue = []
    
    queue.push(pRoot)
    queue.push(pRoot)
    while(queue.length !== 0){
        let a = queue.shift()
        let b = queue.shift()
        if(a === null && b === null){
            continue
        }
        if((!a && b) || (!b && a)){
            return false
        }
        if(a.val !== b.val){
            return false
        }
        queue.push(a.left)
        queue.push(b.right)
        queue.push(a.right)
        queue.push(b.left)
    }
    return true
}
module.exports = {
    isSymmetrical : isSymmetrical
};

二叉树遍历(递归模板)

/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */

// 先序遍历
let res = []
function print(tree){
	if(tree === null){
		return 
	}
	res.push(tree)
	print(tree.left)
	print(tree.right)
}

// 中序遍历
let res = []
function print(tree){
	if(tree === null){
		return 
	}
	print(tree.left)
	res.push(tree)
	print(tree.right)
}

// 后序遍历
let res = []
function print(tree){
	if(tree === null){
		return 
	}
	print(tree.left)
	print(tree.right)
	res.push(tree)
}

二叉树遍历(非递归模板)

先序遍历

算法步骤:
1、先将头放入栈中
2、从栈中弹出一个节点
3、打印(处理)cur
4、先右再左(如果有)
5、直到栈中无元素结束

if(root !== null){
    let s1 = []
    let s2 = []
    s1.push(root)
    while(s1.length !== 0){
        let root = s1.pop()
        s2.push(root.val)
        if(root.right !== null){
            s1.push(root.right)
        }
        if(root.left !== null){
            s1.push(root.left)
        }
    }
    return s2;
}
return []

后序遍历

算法步骤:
1、先将头放入栈中
2、从栈中弹出一个节点cur
3、cur放入收集栈
4、先左再右
5、直到栈中无元素结束,打印收集栈的出栈顺序,即为后序遍历

if(root !== null){
    let s1 = []
    let s2 = []
    s1.push(root)
    while(s1.length !== 0){
        root = s1.pop()
        s2.push(root.val)
        if(root.left !== null){
            s1.push(root.left)
        }
        if(root.right !== null){
            s1.push(root.right)
        }
    }
    return s2.reverse();
}
return []

中序遍历

解题思路:从根节点一直往左入栈,直到为空,就出栈并记录为root,然后再到该root的右子树,继续往左。

if(root !== null){
    let stack = []
    let s = []
    while(stack.length !== 0 || root !== null){
        if(root != null){
            stack.push(root)
            root = root.left
        } else{
            root = stack.pop()
            s.push(root.val)
            root = root.right
        }
    }
    return s
}
return []

层序遍历

解题思路:准备一个队列,先将根节点入队,每次循环出队一次,然后把出队的节点的左右节点都入队,最后出队的顺序就是层序遍历的顺序。

if(root === null){
    return 
} 
let queue = []
queue.push(head)
while(queue.length !== 0){
    let cur = queue.shift()
    console.log(cur)
    if(cur.left !== null){
        queue.push(cur.left)
    }
    if(cur.right !== null){
        queue.push(cur)
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
重建二叉树是一道经典的二叉树,其解题思路如下: 1. 首先,我们需要根据前序遍历序列和中序遍历序列来重建二叉树。前序遍历序列的第一个节点一定是二叉树的根节点,中序遍历序列中根节点左边的所有节点都属于二叉树的左子树,右边的所有节点都属于二叉树的右子树。 2. 我们可以通过前序遍历序列找到二叉树的根节点,然后在中序遍历序列中找到根节点的位置。根节点左边的所有节点都属于左子树,右边的所有节点都属于右子树。 3. 接下来,我们递归构建左子树和右子树。我们可以根据前序遍历序列和中序遍历序列中左右子树的节点数量确定左右子树的范围。 4. 重复以上步骤,直到遍历完整个序列,最终得到重建的二叉树。 下面是重建二叉树代码实现,代码注释中有详细的解释。 ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def buildTree(preorder, inorder): """ :type preorder: List[int] :type inorder: List[int] :rtype: TreeNode """ # 如果前序遍历序列和中序遍历序列为空,返回None if not preorder or not inorder: return None # 前序遍历序列的第一个节点一定是二叉树的根节点 root_val = preorder[0] root = TreeNode(root_val) # 在中序遍历序列中找到根节点的位置 root_index = inorder.index(root_val) # 递归构建左子树和右子树 left_preorder = preorder[1:root_index+1] left_inorder = inorder[:root_index] left = buildTree(left_preorder, left_inorder) right_preorder = preorder[root_index+1:] right_inorder = inorder[root_index+1:] right = buildTree(right_preorder, right_inorder) # 将左右子树连接到根节点上 root.left = left root.right = right return root ``` 以上就是重建二叉树的详细解题思路代码实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值