二叉树高频面试题

一)二叉树数据结构

// 二叉树数据结构
static class Node {
    Node left;  // 左节点
    Node right; // 右节点
    int value;  // 节点的值
	    
    Node (Node left, Node right, int value) {
        this.left = left;
        this.right = right;
        this.value = value;
    }
}
	
private Node root; // 根节点

二)求二叉树最大深度

// 求二叉树最大深度
public int getMaxHeight(Node node) {
    if (node == null) {
        return 0;
    } else {
        // 左节点
        int left = getMaxHeight(node.left);
			
        // 右节点
        int right = getMaxHeight(node.right);
			
        // 返回
        return left > right ? left + 1 : right + 1; // 加1的原因,是因为要算上根节点
    }
}

三)求二叉树最小深度

// 求二叉树最小深度
public int getMinHeight(Node node) {
    if (node == null) {
        return 0;
    }
    return getMin(node);
}
		
private int getMin(Node node) {
    if (node == null) {
        return Integer.MAX_VALUE;
    }
    if (node.left == null && node.right == null) {
        return 1;
    }
		
    // 左节点
    int left = getMin(node.left);
		
    // 右节点
    int right = getMin(node.right);
		
    // 返回
    return left <= right ? left + 1 : right + 1; // 加1的原因,是因为要算上根节点
}

四)求二叉树节点个数

// 求二叉树节点个数
public int getNodeNumber(Node node) {
    if (node == null) {
        return 0;
    }
    // 左节点
    int left = getNodeNumber(node.left);
		
    // 右节点
    int right = getNodeNumber(node.right);
			
    // 返回
    return left + right + 1;
}

五)求二叉树中叶子节点个数

// 求二叉树中叶子节点个数
public int getChildNodeNumber(Node node) {
    if (node == null) {
        return 0;
    }
    if (node.left == null && node.right == null) {
        return 1;
    }
    // 左节点
    int left = getChildNodeNumber(node.left);
			
    // 右节点
    int right = getChildNodeNumber(node.right);
			
    // 返回
    return left + right;
}

六)求二叉树中第k层节点个数

// 求二叉树中第k层节点个数
public int getNodeNumberByK(Node node, int k) {
    if (node == null || k < 1) {
        return 0;
    }
    if (k == 1) {
        return 1;
    }
			
    // 左节点的值
    int left = getNodeNumberByK(node.left, k-1);
			
    // 右节点的值
    int right = getNodeNumberByK(node.right, k-1);
			
    // 返回
    return left + right;
}

七)求二叉树中最大节点的值

// 求二叉树中最大节点的值
public int getMaxValue(Node node) {
    if (node == null) {
        return -1;
    } else {
        // 左节点
        int leftValue = getMaxValue(node.left);
				
        // 右节点
        int rightValue = getMaxValue(node.right);
				
        // 当前值
        int value = node.value;
				
        // 假如左节点的值为最大值
        int max = leftValue;
				
        // 判断右节点的值是否大于当前值
        if (rightValue >= max) {
            max = rightValue;
        }
				
        // 和当前节点比较
        if (value > max) {
            max = value;
        }
        return max;
    }
}

八)判断一个值是否在二叉树中存在

// 判断一个值是否在二叉树中存在
public boolean findValue(int value) {
    if (value <= 0) {
        return false;
    } else {
        // 根节点
        Node rootNode = root;
			
        boolean bool = false;
        while (rootNode != null) {
            // 如果值相等,就返回true
            if (value == rootNode.value) {
                bool = true;
                break;
            } else {
                // 继续查找子节点,对比value
                if(value > rootNode.value) {
                    rootNode = rootNode.right;
                } else {
                    rootNode = rootNode.left;
                }
            }
        }
        return bool;
    }
}

九)判断二叉树是否是平衡二叉树

// 判断二叉树是否是平衡二叉树
public boolean isAVLTree(Node node) {
    return avl(node)!=-1;
}
		
public int avl(Node node) {
    if (node == null) {
        return 0;
    }
    // 左节点
    int left = avl(node.left);
    // 右节点
    int right = avl(node.right);
    if (left == -1 || right == -1 || Math.abs(left-right) > 1) {
        return -1;
    }
    // 返回
    return left > right ? left + 1 : right + 1; // 加1的原因,是因为要算上根节点
}

十)判断两个二叉树是否完全相同

// 判断两个二叉树是否完全相同
public boolean isEquals(Node node1, Node node2) {
    if (node1 == null && node2 == null) {
        return true;
    }
    if (node1 == null || node2 == null) {
        return false;
    }
    if (node1.value != node2.value) {
        return false;
    }
			
    // 左节点
    boolean left = isEquals(node1.left, node2.left);
    // 右节点
    boolean right = isEquals(node1.right, node2.right);
			
    // 返回
    return left && right;
}

十一)判断两个二叉树是否互为镜像

// 判断两个二叉树是否互为镜像
public boolean isImage(Node node1, Node node2) {
    if (node1 == null && node2 == null) {
        return true;
    }
    if (node1 == null || node2 == null) {
        return false;
    }
			
    if (node1.value != node2.value) {
        return false;
    }
			
    // 左节点
    boolean left = isImage(node1.left, node2.right);
    // 右节点
    boolean right = isImage(node1.right, node2.left);
			
    // 返回
    return left && right;
}

十二)二叉树前序遍历: 根节点 ==> 左节点 ==> 右节点

// 二叉树前序遍历: 根节点 ==> 左节点 ==> 右节点
// 方式一: 递归
public void preNode(Node node) {
    if (node != null) {
        System.out.print(node.value + "\t");
				
        preNode(node.left);
				
        preNode(node.right);
    }
}
	
// 方式二: 迭代
public void preNodeWhile(Node node) {
    Stack<Node> stack = new Stack<Node>();
    stack.push(node);
			
    while (!stack.empty()) {
        Node currentnode = stack.pop();
        System.out.print(currentnode.value + "\t");
        if (currentnode.right != null) {
            stack.push(currentnode.right);
        }
        if (currentnode.left != null) {
            stack.push(currentnode.left);
        }
    }
}

十三)二叉树中序遍历: 左节点 ==> 根节点 ==> 右节点

// 二叉树中序遍历: 左节点 ==> 根节点 ==> 右节点
// 方式一: 递归
public void inNode(Node node) {
    if (node != null) {
        inNode(node.left);
				
        System.out.print(node.value + "\t");
				
        inNode(node.right);
    }
}
	
// 方式二: 迭代
public void inNodeWhile(Node node) {
    Stack<Node> stack = new Stack<Node>();
			
    Node current = node;
    while (current != null || !stack.empty()) {
        while (current != null) {
            stack.add(current);
            current = current.left;
        }
				
        current = stack.peek();
        stack.pop();
        System.out.print(current.value + "\t");
        current = current.right;      
    }
}

十四)二叉树后序遍历: 左节点 ==> 右节点 ==> 根节点

// 二叉树后序遍历: 左节点 ==> 右节点 ==> 根节点
// 方式一: 递归
public void nextNode(Node node) {
    if (node != null) {
        nextNode(node.left);
				
        nextNode(node.right);
				
        System.out.print(node.value + "\t");
    }
}
	
// 方式二: 迭代
public void nextNodeWhile(Node node) {
    int left = 1; // 在辅助栈里表示左节点
    int right = 2;// 在辅助栈里表示右节点
		
    Stack<Node> stack = new Stack<Node>();
    Stack<Integer> stack2 = new Stack<Integer>();
			
    // 辅助栈,用来判断子节点返回父节点时处于左节点还是右节点
    while (node != null || !stack.empty()) {
        while (node != null) {
            // 将节点压入栈1,并在栈2将节点标记为左节点	
            stack.push(node);
            stack2.push(left);
            node = node.left;
        }
	    			
        while (!stack.empty() && stack2.peek() == right) {
            // 如果是从右子节点返回父节点,则任务完成,将两个栈的栈顶弹出
            stack2.pop();
            System.out.print(stack.pop().value + "\t");
        }
				
        if (!stack.empty() && stack2.peek() == left) {
            // 如果是从左子节点返回父节点,则将标记改为右子节点
            stack2.pop();
            stack2.push(right);
            node = stack.peek().right;
        }
    }
}

 

识别二维码关注个人微信公众号

本章完结,待续,欢迎转载!
 
本文说明:该文章属于原创,如需转载,请标明文章转载来源!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值