二叉树经典题目
- 1、二叉树的前序遍历
- 2、二叉树的中序遍历
- 3、二叉树的后序遍历
- 4、二叉树的最大深度
- 5、相同的树
- 6、另一棵树的子树
- 7、对称二叉树
- 8、平衡二叉树
- 9、二叉树的层序遍历
- 10、根据字符串,构建二叉树(二叉树遍历)
- 11、两个节点的最近公共祖先
- 12、二叉搜索树与双向链表
- 13、从前序与中序遍历序列构造二叉树
- 14、从中序与后序遍历序列构造二叉树
- 15、根据二叉树创建字符串
1、二叉树的前序遍历
力扣OJ链接
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
List<Integer> list = new ArrayList<>();
public List<Integer> preorderTraversal(TreeNode root) {
if(root == null) return list;
list.add(root.val);
preorderTraversal(root.left);
preorderTraversal(root.right);
return list;
}
}
2、二叉树的中序遍历
力扣OJ链接
给定一个二叉树的根节点 root ,返回它的 中序 遍历。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
List<Integer> list = new ArrayList<>();
public List<Integer> inorderTraversal(TreeNode root) {
if(root == null) return list;
inorderTraversal(root.left);
list.add(root.val);
inorderTraversal(root.right);
return list;
}
}
3、二叉树的后序遍历
力扣OJ链接
给定一个二叉树,返回它的 后序 遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
List<Integer> list = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
if (root == null) return list;
postorderTraversal(root.left);
postorderTraversal(root.right);
list.add(root.val);
return list;
}
}
4、二叉树的最大深度
力扣OJ链接
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
}
5、相同的树
力扣OJ链接
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
} else if (p == null || q == null) {
return false;
} else if (p.val != q.val) {
return false;
}
if(isSameTree(p.left,q.left) && isSameTree(p.right,q.right)){
return true;
}
return false;
}
}
6、另一棵树的子树
力扣OJ链接
给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
} else if (p == null || q == null) {
return false;
} else if (p.val != q.val) {
return false;
}
if(isSameTree(p.left,q.left) && isSameTree(p.right,q.right)){
return true;
}
return false;
}
public boolean isSubtree(TreeNode s, TreeNode t) {
if(s==null || t == null){
return false;
}
if(isSameTree( s, t)){
return true;
}
Boolean ret = isSubtree(s.left,t);
if(ret == true){
return true;
}
ret = isSubtree(s.right,t);
if(ret == true){
return true;
}
return false;
}
}
7、对称二叉树
力扣OJ链接
给定一个二叉树,检查它是否是镜像对称的。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree) {
if(leftTree == null && rightTree == null){
return true;
}
if(leftTree == null &&rightTree != null || leftTree != null && rightTree == null){
return false;
}
if(leftTree.val != rightTree.val) return false;
return isSymmetricChild(leftTree.left,rightTree.right) && isSymmetricChild(leftTree.right,rightTree.left);
}
public boolean isSymmetric(TreeNode root) {
if(root == null){
return true;
}
if(isSymmetricChild(root.left,root.right)){
return true;
}
return false;
}
}
8、平衡二叉树
力扣OJ链接
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int getHeight(TreeNode root){
if(root == null){
return 0;
}
return Math.max(getHeight(root.left),getHeight(root.right)) +1;
}
public boolean isBalanced(TreeNode root) {
if(root == null) return true;
return Math.abs(getHeight(root.left)-getHeight(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);
}
}
9、二叉树的层序遍历
力扣OJ链接
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ret = new ArrayList<>();
if(root == null) return ret;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
TreeNode cur = new TreeNode();
while(!queue.isEmpty()) {
List<Integer>list = new ArrayList<>();
int size = queue.size();
while(size >0){
cur = queue.poll();
list.add(cur.val);
if(cur.left != null){
queue.add(cur.left);
}
if(cur.right != null ){
queue.add(cur.right);
}
size--;
}
ret.add(list);
}
return ret;
}
}
10、根据字符串,构建二叉树(二叉树遍历)
牛客链接
编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。
import java.util.*;
class BTNode{
public char val;
public BTNode left;//左子树的引用
public BTNode right;//右子树的引用
public BTNode(char val){
this.val = val;
}
}
public class Main{
public static int i = 0;
public static BTNode creatTree(String str){
if(str == null || str.length() < 0) return null;
BTNode root = null;
if(str.charAt(i) != '#'){
root = new BTNode(str.charAt(i));
i++;
root.left = creatTree(str);
root.right = creatTree(str);
}else{
i++;
}
return root;
}
public static void inOrderTraversal(BTNode root) {
if (root == null) return;
inOrderTraversal(root.left);
System.out.print(root.val + " ");
inOrderTraversal(root.right);
}
public static void main(String[]args){
Scanner scan = new Scanner(System.in);
String str = scan.nextLine();
BTNode root = creatTree(str);
inOrderTraversal(root);
}
}
11、两个节点的最近公共祖先
力扣OJ链接
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return null;
if(root == p || root == q){
return root;
}
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
if( left != null && right != null){
return root;
}else if(left != null && right == null){
return left;
}else if(left == null && right != null){
return right;
}else{
return null;
}
}
}
12、二叉搜索树与双向链表
牛客链接
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public TreeNode prev = null;
public void ConvertChild(TreeNode pCur) {
if( pCur == null) return;
ConvertChild(pCur.left);
pCur.left = prev;
if(prev != null){
prev.right = pCur;
}
prev = pCur;
ConvertChild(pCur.right);
}
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree == null) return null;
ConvertChild(pRootOfTree);
TreeNode head = pRootOfTree;
while(head.left != null){
head = head.left;
}
return head;
}
}
13、从前序与中序遍历序列构造二叉树
力扣OJ链接
给定一棵树的前序遍历 preorder 与中序遍历 inorder。请构造二叉树并返回其根节点。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int preIndex = 0;
public TreeNode buildTreeChild(int[] preorder,int[] inorder,int inbegin,int inend){
if(inbegin > inend) return null;
TreeNode root = new TreeNode(preorder[preIndex]);
//在中序遍历的数组当中找到当前根节点的位置
int index = findvalInorder(inorder,preorder[preIndex],inbegin,inend);
preIndex++;
root.left = buildTreeChild(preorder,inorder,inbegin,index-1);
root.right = buildTreeChild(preorder,inorder,index+1,inend);
return root;
}
public int findvalInorder(int[] inorder,int key,int inbegin,int inend){
for(int i = inbegin;i<=inend;i++){
if(inorder[i] == key){
return i;
}
}
return -1;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder == null || inorder == null) return null;
if(preorder.length == 0 || inorder.length == 0) return null;
return buildTreeChild(preorder,inorder,0,inorder.length-1);
}
}
14、从中序与后序遍历序列构造二叉树
力扣OJ链接
根据一棵树的中序遍历与后序遍历构造二叉树。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int posIndex = 0;
public TreeNode buildTreeChild(int[] postorder,int[] inorder,int inbegin,int inend){
if(inbegin > inend) return null;
TreeNode root = new TreeNode(postorder[posIndex]);
//在中序遍历的数组当中找到当前根节点的位置
int index = findvalInorder(inorder,postorder[posIndex],inbegin,inend);
posIndex--;
root.right = buildTreeChild(postorder,inorder,index+1,inend);
root.left = buildTreeChild(postorder,inorder,inbegin,index-1);
return root;
}
public int findvalInorder(int[] inorder,int key,int inbegin,int inend){
for(int i = inbegin;i<=inend;i++){
if(inorder[i] == key){
return i;
}
}
return -1;
}
public TreeNode buildTree(int[] inorder, int[] postorder) {
if(postorder == null || inorder == null) return null;
if(postorder.length == 0 || inorder.length == 0) return null;
posIndex = postorder.length-1;
return buildTreeChild(postorder,inorder,0,inorder.length-1);
}
}
15、根据二叉树创建字符串
力扣OJ链接
你需要采用前序遍历的方式,将一个二叉树转换成一个由括号和整数组成的字符串。
空节点则用一对空括号 “()” 表示。而且你需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public void tree2strChild(TreeNode t,StringBuilder sb ) {
if(t == null) return;
sb.append(t.val);
if(t.left == null){
if(t.right == null){
return;
}else{
sb.append("()");
}
}else{
sb.append("(");
tree2strChild(t.left,sb);
sb.append(")");
}
if(t.right == null){
return ;
}else{
sb.append("(");
tree2strChild(t.right,sb);
sb.append(")");
}
}
public String tree2str(TreeNode t) {
StringBuilder sb = new StringBuilder();
tree2strChild(t,sb);
return sb.toString();
}
}