上次写了二叉树遍历,其中在非递归的遍历中,只写了前序遍历,没有写非递归中序遍历和后续遍历。非递归要用到栈,只要根据目标输出顺序反推出节点进栈顺序即可。后续遍历有些麻烦,最好用两个栈来实现(其实一个栈也可以的,借助临时空间,这要求我们搞清楚元素弹出栈的条件和进栈条件)
对于二叉树的操作,如果对算法研究的不深,再加上平时写代码能力一般,建议还是首选递归。虽然递归的效率比非递归要低,但是写的代码比较少,并且容易理解。那么递归的关键点在于递归的出口(边界条件一定要想清楚,有时不仅仅只是考虑二叉树头结点为null的情况,还有其他的情况)下面列举几种二叉树的相关操作,大部分来源于剑指offer上的题目。建议各位计算机专业的同学多多刷题,推荐一个很好的学习网站——牛客网,里面很多高手。
1.重建二叉树
给出二叉树的前序遍历和中序遍历,要求得到这课二叉树
import java.util.Arrays;
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre==null || in==null){
return null;
}
if(pre.length==0){return null;}
int val=pre[0];
TreeNode root=new TreeNode(val);
int index=-1;
for(int i=0;i< in.length;i++){
if(in[i]==val){
index=i;
}
}
if(index==-1) return null;
root.left=reConstructBinaryTree(Arrays.copyOfRange(pre,1, index+1),Arrays.copyOfRange(in,0,index));
root.right=reConstructBinaryTree(Arrays.copyOfRange(pre,index+1,pre.length),Arrays.copyOfRange(in,index+1,in.length));
return root;
}
}
以上程序的关键部分是java中的工具类Arrays的方法copyOfRange,这就看平时玩API的熟练程度了,也反映java的基本功啊~~~
2.输入两颗二叉树A,B,判断B是不是A的子结构。
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
boolean result = false;
if(root1!=null&&root2!=null){
if(root1.val==root2.val)
result = DoesTree1HaveTree2(root1,root2);
if(!result)
result = HasSubtree(root1.left,root2);
if(!result)
result = HasSubtree(root1.right,root2);
}
return result;
}
//如果root1中某一节点的值和root2的根节点的值相同再继续判断
private boolean DoesTree1HaveTree2(TreeNode root1, TreeNode root2){
if(null==root2)
return true;
if(null==root1)
return false;
if(root1.val!=root2.val)
return false;
boolean s1 = DoesTree1HaveTree2(root1.left, root2.left);
boolean s2 = DoesTree1HaveTree2(root1.right, root2.right);
return s1&&s2;
}
}
3.二叉树镜像
操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:
二叉树的镜像定义:源二叉树
8
/ \
6 10
/ \ / \
5 7 9 11
镜像二叉树
8
/ \
10 6
/ \ / \
11 9 7 5
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public void Mirror(TreeNode root) {
if (null == root)
return;
if (root.left == null && root.right == null)
return;
//就是把左子树和右子树交换就OK啦
TreeNode p = root.left;
root.left = root.right;
root.right = p;
if (root.left != null)
Mirror(root.left);
if (root.right != null)
Mirror(root.right);
}
}
4.二叉搜索树的后序遍历序列
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
public class Solution {
public boolean VerifySquenceOfBST(int [] sequence) {
if(null==sequence||sequence.length<=0)
return false;
int length = sequence.length;
boolean result = IsSequenceOfBST(sequence,length);
return result;
}
private boolean IsSequenceOfBST(int[] sequence, int length){
if(null==sequence||length<=0)
return false;
boolean left = true;
boolean right = true;
int root = sequence[length-1];
int i=0;
//左子树要小于根节点
for(;i if(sequence[i]>root){ break; } } //右子树要大于跟节点 int j=i; for(;j if(sequence[j] return false; } } if(i>0) left = IsSequenceOfBST(sequence,i); if(i right = IsSequenceOfBST(sequence,length-i-1); return (left&&right); } } 从上往下打印出二叉树的每个节点,同层节点从左至右打印。 import java.util.ArrayList; import java.util.LinkedList; /** public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } */ public class Solution { public ArrayListPrintFromTopToBottom(TreeNode root) { ArrayListaList LinkedListlList if(root==null) return aList; lList.push(root); while(lList.size()>0){ if(lList.peek().left!=null){ lList.add(lList.peek().left);//这里要用add,push会超过内存限制 } if(lList.peek().right!=null){ lList.add(lList.peek().right); } aList.add(lList.poll().val); } return aList; } } 还有更多的二叉树操作,以后再写5.从上到下打印二叉树