二叉树练题总结,不定时更新
素材来自牛客网,参考题解已附注超链接,侵删 联系邮箱:zhenyu_li1998@163.com
二叉树先序中序后序遍历
递归遍历即可
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类 the root of binary tree
* @return int整型二维数组
*/
private List<Integer> list = new ArrayList<>();
public int[][] threeOrders (TreeNode root) {
// write code here
if(root == null){
return new int[3][0];
}
preOrder(root);
midOrder(root);
afterOrder(root);
//定义返回数组长度,子数组长度为list的1/3
int[][] res = new int[3][list.size() / 3];
int index = 0;
for(int i = 0; i < 3; i++){
for(int j = 0; j < list.size() / 3; j++){
res[i][j] = list.get(index);
index++;
}
}
return res;
}
//根左右
public void preOrder(TreeNode root){
if(root == null){
return;
}
list.add(root.val);
preOrder(root.left);
preOrder(root.right);
}
//左根右
public void midOrder(TreeNode root){
if(root == null){
return;
}
midOrder(root.left);
list.add(root.val);
midOrder(root.right);
}
//左右根
public void afterOrder(TreeNode root){
if(root == null){
return;
}
afterOrder(root.left);
afterOrder(root.right);
list.add(root.val);
}
}
二叉树层序遍历
利用队列先进先出的性质存储依次存储每层节点并加入队列用于返回
1.先判断根节点;为空则直接返回空的数组;不为空则加入队列进行遍历;
2.遍历次数为队列长度,出队后加入数组,并将其左右孩子节点加入队列;因为队列长度在每次遍历前由一个变量更新存储且队列先进先出,因此加入孩子节点不会影响当前(此层)遍历结果;
3.每次遍历完成后将当前数组以子数组形式加入定义的返回数组,然后判断队列是否为空(如果没孩子节点加入自然为空)再进行2操作或退出循环返回父数组
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @return int整型ArrayList>
*/
public ArrayList> levelOrder (TreeNode root) {
// write code here
Queue que = new ArrayDeque();
if(root != null){
que.add(root);
}
ArrayList> res = new ArrayList();
while(!que.isEmpty()){
ArrayList list = new ArrayList();
// 遍历队列将其中的元素加入数组(层序遍历)
int n = que.size();
for(int i = 0; i < n; i++){
TreeNode node = que.poll();
list.add(node.val);
// 将当前节点的左右孩子节点加入队列
if(node.left != null){
que.add(node.left);
}
if(node.right != null){
que.add(node.right);
}
}
// 将每层的元素以子数组形式加入新的数组
res.add(list);
}
return res;
}
}
判断二叉树对称
正是因为要遍历两棵树而且要比较内侧和外侧节点,所以准确的来说是一个树的遍历顺序是左右中,一个树的遍历顺序是右左中。
但都可以理解算是后序遍历,尽管已经不是严格上在一个树上进行遍历的后序遍历了。
迭代实现: 通过队列来判断根节点的左子树和右子树的内侧和外侧是否相等。同样也可以通过栈来存储节点出栈对比
public boolean isSymmetric (TreeNode root) {
// write code here
if(root == null) return true;
Queue<TreeNode> que = new LinkedList<>();
// 将左右子树头结点加入队列
que.offer(root.left);
que.offer(root.right);
while(!que.isEmpty()){
TreeNode leftNode = que.poll();
TreeNode rightNode = que.poll();
// 左节点为空、右节点为空,此时说明是对称的
if(leftNode == null && rightNode == null){
continue;
}
// 左右一个节点不为空 或者都不为空但数值不相同,返回false
if(leftNode == null || rightNode == null || (leftNode.val != rightNode.val)){
return false;
}
// 加入左节点左孩子 右节点右孩子 * 左节点右孩子 加入右节点左孩子
que.offer(leftNode.left);
que.offer(rightNode.right);
que.offer(leftNode.right);
que.offer(rightNode.left);
}
return true;
}