二叉树
/** * 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<Integer> list = new ArrayList<>(); public List<Integer> preorderTraversal(TreeNode root) { bianLi(root); return list; } public void bianLi(TreeNode root) { if (root == null) { return; } list.add(root.val); bianLi(root.left); bianLi(root.right); } }
class Solution { public List<Integer> list = new ArrayList<>(); public List<Integer> inorderTraversal(TreeNode root) { bianLi(root); return list; } public void bianLi(TreeNode root) { if (root == null) { return; } bianLi(root.left); list.add(root.val); bianLi(root.right); } }
class Solution { public List<Integer> list = new ArrayList<>(); public List<Integer> postorderTraversal(TreeNode root) { bianLi(root); return list; } public void bianLi(TreeNode root) { if (root == null) { return; } bianLi(root.left); bianLi(root.right); list.add(root.val); } }
import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Queue; class Solution { public Queue<TreeNode> queue = new LinkedList<>(); public List<List<Integer>> levelOrder(TreeNode root) { // 如果根结点为空,返回空集合 if (root == null) { return new ArrayList<>(); } List<List<Integer>> lists = new ArrayList<>(); queue.offer(root); while (!queue.isEmpty()) { // 存放每次的结点值 List<Integer> list = new ArrayList<>(); // 每层的结点数 int levelNum = queue.size(); // 从左向右依次遍历每层的节点 for (int i = 0; i < levelNum; i++) { // 将该层的节点值放进list集合 TreeNode node = queue.poll(); list.add(node.val); // 将该节点不为空的左右节点按顺序添加进队列 if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } lists.add(list); } return lists; } } 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; } }
二,根据二叉树的遍历还原二叉树
1.根据二叉树的中序遍历和后序遍历还原二叉树
题目描述
代码实现
import java.util.HashMap; import java.util.Map; class Solution { public Map<Integer, Integer>map=new HashMap<>(); // inorder:中序遍历结果,postorder后序遍历结果 public TreeNode buildTree(int[] inorder, int[] postorder) { for(int i=0;i<inorder.length;i++) { map.put(inorder[i], i); } return DTBuildTree(inorder, postorder, 0, inorder.length - 1,0,inorder.length - 1); } private TreeNode DTBuildTree(int[] inorder, int[] postorder, int head1, int end1,int head2,int end2) { if (head1 == end1) { return new TreeNode(inorder[head1]); } if (head1 > end1) { return null; } // 获取根结点的值 int val = postorder[end2]; // 创建根结点 TreeNode rootNode = new TreeNode(val); // 找到根结点在中序遍历中出现的下标 int mid =map.get(val); int leftSize=mid-head1; // 以根结点来划分中序遍历中左右子树,mid左边是左子树,右边是右子树 rootNode.left = DTBuildTree(inorder, postorder, head1, mid - 1,head2,head2+leftSize-1); rootNode.right = DTBuildTree(inorder, postorder, mid + 1, end1,head2+leftSize,end2-1); return rootNode; } }
2.根据二叉树的前序遍历和中序遍历还原二叉树
题目描述
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
代码实现
import java.util.HashMap; import java.util.Map; import java.util.HashMap; import java.util.Map; class Solution { int[] preorder; int[] inorder; public Map<Integer, Integer> map = new HashMap<>(); public TreeNode buildTree(int[] preorder, int[] inorder) { this.preorder = preorder; this.inorder = inorder; for (int i = 0; i < inorder.length; i++) { map.put(inorder[i], i); } return DTbuildTree(0, preorder.length - 1, 0, inorder.length - 1); } //head1和end1为先序遍历起点和终点,head2和end2为中序遍历起点和终点 public TreeNode DTbuildTree(int head1, int end1, int head2, int end2) { if (head2 > end2) { return null; } if (head2 == end2) { return new TreeNode(inorder[head2]); } int val = preorder[head1]; int mid = map.get(val); TreeNode rooTreeNode = new TreeNode(val); //leftSize为左节点个数,中序遍历中根节点减去中序遍历的起点 int leftSize = mid-head2; rooTreeNode.left = DTbuildTree(head1 + 1, leftSize, head2, mid - 1); //右边先序遍历的起点为起点加1再加上左节点个数,中序遍历为右边子树的起点为根节点下标加一 rooTreeNode.right = DTbuildTree(head1+leftSize + 1, end1, mid + 1, end2); return rooTreeNode; }; }
链接:https://leetcode-cn.com/leetbook/read/data-structure-binary-tree/xoei3r/
3.根据二叉树先序遍历还原二叉树
题目描述
在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。
如果节点只有一个子节点,那么保证该子节点为左子节点。
给出遍历输出 S,还原树并返回其根节点 root。
代码实现
class Solution { public int index = 0; public TreeNode recoverFromPreorder(String traversal) { if (traversal == null) { return null; } return genTree(0, traversal); } private TreeNode genTree(int depth, String traversal) { // TODO Auto-generated method stub // 1.获取该节点深度 int curDepth = 0; while (index < traversal.length() && traversal.charAt(index) == '-') { curDepth++; index++; } // 2.比较该节点深度和目标深度是否相等,如果不相等,则说明该位置节点为null,该节点是上一层的子节点,index退回到刚进入该方法的值 if (curDepth != depth) { index -= curDepth; return null; } // 3.获取该节点的值 int val = 0; while (index < traversal.length() && Character.isDigit(traversal.charAt(index))) { int t = traversal.charAt(index) - '0'; val = val * 10 + t; index++; } // 4.创建节点(将值放入构造器),深度加一,将创建节点的左右节点赋值,返回创建节点 TreeNode treeNode = new TreeNode(val); // 如果节点只有一个子节点,那么保证该子节点为左子节点 treeNode.left = genTree(depth + 1, traversal); treeNode.right = genTree(curDepth + 1, traversal); return treeNode; } }
三,完全二叉树
1.如何判断完全二叉树
判断一棵树是否是完全二叉树的思路 [3] 1>如果树为空,则直接返回错 2>如果树不为空:层序[遍历](https://baike.baidu.com/item/遍历/9796023)二叉树 2.1>如果一个结点左右孩子都不为空,则pop该节点,将其左右孩子入队列; 2.1>如果遇到一个结点,左孩子为空,右孩子不为空,则该树一定不是完全二叉树; 2.2>如果遇到一个结点,左孩子不为空,右孩子为空;或者左右孩子都为空,且则该节点之后的队列中的结点都为叶子节点,该树才是完全二叉树,否则就不是完全二叉树; [3]
2.根据完全二叉树的后序遍历求层序遍历
题目描述:
一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是完美二叉树。对于深度为 D 的,有 N 个结点的二叉树,若其结点对应于相同深度完美二叉树的层序遍历的前 N 个结点,这样的树就是完全二叉树。
输入格式
输入在第一行中给出正整数 N(≤30),即树中结点个数。第二行给出后序遍历序列,为 N 个不超过 100 的正整数。同一行中所有数字都以空格分隔。
输出格式
在一行中输出该树的层序遍历序列。所有数字都以 1 个空格分隔,行首尾不得有多余空格。
输入样例
8 91 71 2 34 10 15 55 18
18 34 55 71 2 10 15 91
思路分析
由于其是完全二叉树,所以可以考虑用序号递归,模拟后序遍历来求解(只有完全二叉树和满二叉树可以考虑用这种方法求解)
代码实现
import java.util.Scanner; public class Main { public static int[] tree; public static int n, now; public static int []post; public static void main(String[] args) { Scanner sca=new Scanner(System.in); n=sca.nextInt(); tree=new int[n+1]; post=new int[n+1]; for (int i = 0; i < n; i++) { post[i]=sca.nextInt(); } build(1); for (int i = 1; i <= n; i++) { if (i != 1) System.out.print(" "); System.out.print(tree[i]); } } //因为其是完全二叉树(只有完全二叉树和满二叉树才可用该方法) //所以除了最后一层不是满的,其它层均是满的 //有右孩子就必定有左孩子 //根结点设为1,左节点为2,右节点为3,依次类推,可以发现左节点等于根节点*2,右节点等于根节点*2+1,由于从1开始编号,所以编号超过节点总数的时候说明没有该节点 public static void build(int root) { if (root > n) return; //递归左节点 build(root * 2); //递归右节点 build(root * 2 + 1); tree[root] = post[now++]; } }
补充方法,根据完全二叉树的 后序遍历来还原二叉树
private static TreeNode buildTreeT(int xh) { if (xh > n) { return null; } TreeNode root = new TreeNode(); root.left = buildTreeT(xh * 2); root.right = buildTreeT(xh * 2 + 1); root.val = post[now++]; return root; }
本文来自博客园,作者:lzstar-A2,转载请注明原文链接:https://www.cnblogs.com/lzstar/p/15399235.html
作 者:lzstar-A2
出 处:https://www.cnblogs.com/lzstar/
关于作者:一名java转安全的在校大学生
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!
欢迎大家关注安全学习交流群菜鸟联盟(IThonest),如果您觉得文章对您有很大的帮助,您可以考虑赏博主一杯可乐以资鼓励,您的肯定将是我最大的动力。thx.
菜鸟联盟(IThonest),一个可能会有故事的qq群,欢迎大家来这里讨论,共同进步,不断学习才能不断进步。扫下面的二维码或者收藏下面的二维码关注吧(长按下面的二维码图片、并选择识别图中的二维码),个人QQ和微信的二维码也已给出,扫描下面👇的二维码一起来讨论吧!!!