二叉树的相关问题
因为二叉树是由许多棵子树子树组成的,因此一个大问题可以转换为许多个相同的小问题,因此这里关于二叉树的问题多采用递归实现。
求二叉树的节点个数
思路:
拿到二叉树的根节点,若根节点为空,则节点个数为0;
若根节点不是空,则二叉树的节点个数为左子树的节点个数+右子树的节点个数+1(根节点)
1.使用递归实现求二叉树的节点个数
int getSize2(Node root) {
if(root == null){
return 0;
}
return getSize2(root.left)+getSize2(root.right)+1;
}
2.使用遍历的思想求二叉树的节点个数
static int size = 0;
int getSize1(Node root) {
if(root == null){
return 0;
}
size++;
getSize1(root.left);
getSize1(root.right);
return size;
}
求二叉树叶子节点的个数
思路:拿到二叉树的根节点,有三种情况:
若根节点为空,则叶子节点的个数为0;
若根节点不为空,左右子树为空,则叶子节点的个数为1;
根节点不为空,叶子节点不为空求得左子树叶子节点和右子树的叶子结点的总和即可。
1.使用递归的方法求二叉树的叶子节点
int getLeafSize2(Node root) {
if(root == null){
return 0;
}
if(root.left == null && root.right == null){
return 1;
}
return getLeafSize2(root.left)+getLeafSize2(root.right);
}
2.使用遍历的思路求二叉树的叶子节点的个数
static int leafSize = 0;
int getLeafSize1(Node root) {
if(root == null){
return 0;
}
if(root.left == null && root.right == null){
leafSize++;
}
getLeafSize1(root.left);
getLeafSize1(root.right);
return leafSize;
}
根据val值查找对应节点
根据val查找对应节点,没有找到返回null;
根据根节点-左子树-右子树的顺序进行查找
一旦找到,立即返回,不需要在继续在其他位置查找
Node find(Node root, int val) {
if(root == null){
return null;
}
if(root.value == val){
return root;
}
//接收find的返回值,判断左子树是否找到
Node ret = find(root.left,val);
if(ret != null){
return ret;
}
Node ret2 = find(root.right,val);
if(ret2 != null){
return ret2;
}
return null;
}
求二叉树的最大深度
二叉树的深度,根节点为第一层,以此类推、
二叉树的最大深度:左子树深度和右子树深度的最大值+1
思路:求二叉树的最大深度,
1)拿到树的根节点,求出左子树的最大深度和右子树的最大深度两者比较,谁大取谁
2)最终的二叉树的最大深度为1)取得的大的一个+1
public int maxDepth(Node root){
if(root == null){
return 0;
}
int leftHight = maxDepth(root.left);
int rightHight = maxDepth(root.right);
return (leftHight > rightHight) ? leftHight+1:rightHight+1;
}
判断一个树是否为平衡二叉树
平衡二叉树的定义:一个二叉树的每个节点的左右两个子树的高度差的绝对值不超过1
思路:
拿到树的根节点,求得左子树和右子树的最大深度差,差值不超过1并且左子树和右子树都平衡才是平衡二叉树。
public boolean isBalanced(Node root) {
if(root == null){
return true;
}
int x = maxDepth(root.left)-maxDepth(root.right);
return Math.abs(x)<2 && isBalanced(root.left) && isBalanced(root.right);
}
判断一个树是否为对称二叉树
对称二叉树:
看了图应该思路就很清晰了:
public boolean isSymmetric(Node root) {
if(root == null){
return true;
}
return isSymmetricChild(root.left,root.right);
}
public boolean isSymmetricChild(Node leftTree,Node rightTree){
if(leftTree == null && rightTree == null){
return true;
}
if(leftTree != null && rightTree == null || leftTree == null && rightTree != null){
return false;
}
return (leftTree.value == rightTree.value) && isSymmetricChild(leftTree.left,rightTree.right)&&
isSymmetricChild(leftTree.right,rightTree.left);
}
判断是否为完全二叉树
是否为完全二叉树:
利用队列实现
1) 拿到根节点,若不是空,则将其左节点与右节点放入队列;
2)获取队头元素并出队,若不为空,则将该节点左右节点均入队;
3)若获取的节点为null,则判断队列中其余元素是否为null;若是,则是完全二叉树;若不是,则不是完全二叉树
boolean isCompleteTree(Node root){
Queue<Node> queue = new LinkedList<>();
if(root == null){
return true;
}
queue.offer(root);
while(!queue.isEmpty()){
Node cur = queue.poll();
if(cur != null){
queue.offer(cur.left);
queue.offer(cur.right);
} else {
break;
}
}
//当获取的对头元素为空时,走到这里,遍历队列若队列元素全为空,则说明是完全二叉树
while(!queue.isEmpty()) {
Node curn = queue.poll();
if (curn != null) {
return false;
}
}
return true;
}
获取第K层节点的个数
递归:求根为root的二叉树第k层节点的个数,就是要求 root.left第k-1层节点的个数+ root.right第k-1层节点的个数
int getKLevelSize(Node root,int k){
if(root == null || k <= 0){
return 0;
}
if(k == 1){
return 1;
}
int leftLevelsize = getKLevelSize(root.left,k-1);
int rightLevelsize = getKLevelSize(root.right,k-1);
return leftLevelsize+rightLevelsize;
}