重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回
代码
前序遍历:根左右。先打印,再遍历左子树,再遍历右子树;
中序遍历:左根右。先遍历左子树,再打印,再遍历右子树;
后序遍历:左右根。先遍历左子树,再遍历右子树,再打印
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if (pre == null || pre.length == 0){
return null;
}
if (pre.length == 1){
return new TreeNode(pre[0]);
}
//定义根节点
TreeNode root = new TreeNode(pre[0]);
int index = 0;
for( int i=0;i<in.length;i++){
if (pre[0] == in[i]){
index = i;
break;
}
}
//将数组分割为左右两部分
int[] pre_left = new int[index];
for (int i=0;i<index;i++){
pre_left[i] = pre[i+1];
}
int[] pre_right = new int[pre.length - index -1];
for (int i=0;i<pre.length-index-1;i++){
pre_right[i] = pre[index+i+1];
}
int[] in_left = new int[index];
for (int i=0;i<index;i++){
in_left[i] = in[i];
}
int[] in_right = new int[in.length - index -1];
for (int i=0;i<in.length-index-1;i++){
in_right[i] = in[index+i+1];
}
//递归调用
root.left = reConstructBinaryTree(pre_left, in_left);
root.right = reConstructBinaryTree(pre_right, in_right);
return root;
}
}
二叉树的下一个节点
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
代码
1、判断是否是非叶子节点和没有右节点的节点
2、判断值是否是左叶子节点或者是又叶子节点
该二叉树符合平衡二叉树
if (pNode == null){
return null;
}
if (pNode.right != null){
pNode = pNode.right;
while (pNode.left != null) {
pNode = pNode.left;
}
return pNode;
}
while (pNode.next != null){
if (pNode.next.left == pNode){//如果相等,则是左叶子节点
return pNode.next;}
pNode = pNode.next;
}
return null;
对称的二叉树
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
代码
利用递归的方法,来判断左右子树是否对称相等
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
boolean isSymmetrical(TreeNode pRoot)
{
if (pRoot == null){
return true;
}
return isSummer(pRoot.left, pRoot.right);
}
public boolean isSummer(TreeNode left, TreeNode right){
if (left == null || right == null)
return left == right;
if (left.val != right.val)
return false;
return isSummer(left.left, right.right) && isSummer(left.right, right.left);
}
}
按之字形打印二叉树
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
代码
import java.util.ArrayList;
import java.util.List;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
if (pRoot == null){
return new ArrayList<>();
}
//将每一行的数据放入list中
List<TreeNode> list = new ArrayList<>();
list.add(pRoot);
ArrayList<ArrayList<Integer>> arrayLists = new ArrayList<>();
int index = 1;//记录行数
ArrayList<Integer> val = new ArrayList<>();
val.add(pRoot.val);
arrayLists.add(val);
index++;
while (list.size() != 0){
//将节点的数据保存到list表中
list = listQuen(list);
if (list.size() == 0){
break;
}
ArrayList<Integer> integers = new ArrayList<>();//记录节点数据
if (index % 2 == 1){
for (TreeNode t:list){
integers.add(t.val);
}
}else {
for (int i=list.size()-1;i>=0;i--){
integers.add(list.get(i).val);
}
}
index++;
arrayLists.add(integers);
}
return arrayLists;
}
public static List<TreeNode> listQuen(List<TreeNode> list){
List<TreeNode> nodeList = new ArrayList<>();
for (int i=0;i<list.size();i++){
if (list.get(i).left != null){
nodeList.add(list.get(i).left);
}
if (list.get(i).right != null){
nodeList.add(list.get(i).right);
}
}
return nodeList;
}
}
把二叉树打印多行
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
代码
import java.util.ArrayList;
import java.util.List;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
//将每一行的数据放入list中
if (pRoot == null){
return new ArrayList<>();
}
List<TreeNode> list = new ArrayList<>();
list.add(pRoot);
ArrayList<ArrayList<Integer>> arrayLists = new ArrayList<>();
int index = 1;//记录行数
ArrayList<Integer> val = new ArrayList<>();
val.add(pRoot.val);
arrayLists.add(val);
index++;
while (list.size() != 0){
//将节点的数据保存到list表中
list = listQuen(list);
if (list.size() == 0){
break;
}
ArrayList<Integer> integers = new ArrayList<>();//记录节点数据
// if (index % 2 == 1){
// for (TreeNode t:list){
// integers.add(t.val);
// }
// }else {
// for (int i=list.size()-1;i>=0;i--){
// integers.add(list.get(i).val);
// }
// }
// index++;
//从左到右记录
for (TreeNode t:list){
integers.add(t.val);
}
arrayLists.add(integers);
}
return arrayLists;
}
public static List<TreeNode> listQuen(List<TreeNode> list){
List<TreeNode> nodeList = new ArrayList<>();
for (int i=0;i<list.size();i++){
if (list.get(i).left != null){
nodeList.add(list.get(i).left);
}
if (list.get(i).right != null){
nodeList.add(list.get(i).right);
}
}
return nodeList;
}
}
序列化二叉树
请实现两个函数,分别用来序列化和反序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
代码
public class Solution {
String Serialize(TreeNode root) {
if(root == null)
return "";
StringBuilder sb = new StringBuilder();
Serialize2(root, sb);
return sb.toString();
}
void Serialize2(TreeNode root, StringBuilder sb) {
if(root == null) {
sb.append("#,");
return;
}
sb.append(root.val);
sb.append(',');
Serialize2(root.left, sb);
Serialize2(root.right, sb);
}
int index = -1;
TreeNode Deserialize(String str) {
if(str.length() == 0)
return null;
String[] strs = str.split(",");
return Deserialize2(strs);
}
TreeNode Deserialize2(String[] strs) {
index++;
if(!strs[index].equals("#")) {
TreeNode root = new TreeNode(0);
root.val = Integer.parseInt(strs[index]);
root.left = Deserialize2(strs);
root.right = Deserialize2(strs);
return root;
}
return null;
}
二叉搜索树第k个节点
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
代码
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
import java.util.*;
public class Solution {
TreeNode KthNode(TreeNode pRoot, int k)
{
if(k <= 0){
return null;
}
//查出每个节点的值
List<TreeNode> list = new ArrayList<>();
KthNode2(pRoot,list);
Collections.sort(list, new Comparator<TreeNode>() {
@Override
public int compare(TreeNode o1, TreeNode o2) {
return o1.val - o2.val;
}
});
if(k > list.size()){
return null;
}
return list.get(k-1);
}
public void KthNode2(TreeNode treeNode, List<TreeNode> list){
if (treeNode == null){
return ;
}
list.add(treeNode);
KthNode2(treeNode.left, list);
KthNode2(treeNode.right,list);
}
}