二叉树相关操作:构建、遍历、公共父节点等
import java.util.*;
//树节点类
class Node{
public int data;//节点的数值
public Node left;//左子节点
public Node right;//右子节点
public int leftMaxDistance;
public int rightMaxDistance;
//构造函数
public Node(){
}
public Node(int data){
this.data=data;
this.left=null;
this.right=null;
}
}
public class BinSortTree {
private Node root;//根节点
//构造函数
public BinSortTree(){
root=null;
}
/*
* 将数据插入到排序二叉树中—-->左子树数值小于根节点数值,右子树数值大于根节点数值
*/
public void insertData(int data){
Node newNode=new Node(data);
if(root==null)
root=newNode;
else{
Node current=root;
Node parent;
while(true){
parent=current;
//小于当前节点的值,应插入到左子树
if(data<current.data){
current=current.left;
if(current==null){
parent.left=newNode;//找到位置后,插入数据
return;//跳出循环,结束函数
}
}
//大于当前节点的值,应插入到右子树
else{
current=current.right;
if(current==null){
parent.right=newNode;
return;
}
}
}
}
}
//创建二叉排序树
public void buildTree(int[] data){
for (int i = 0; i < data.length; i++) {
insertData(data[i]);
}
}
//根据先序遍历结果和中序遍历结果构造二叉树(根节点数值唯一)
public static Node createBinaryTree(int[] preOrder,int preStart,int preEnd,int[] inOrder,int inStart,int inEnd)
{
if(preOrder.length==0||inOrder.length==0||preOrder==null||inOrder==null||preOrder.length!=inOrder.length||preStart>preEnd||inStart>inEnd)
return null;
int data =preOrder[preStart];//先序遍历第一个值为根节点的值
Node root=new Node(data);//根据根节点的值构造根节点
//找到中序遍历中根节点的位置
int rootIndex=0;
for(rootIndex=inStart;rootIndex<=inEnd;rootIndex++){
if(inOrder[rootIndex]==data)
break;
}
/*
* 递归求解左子树: 左子树先序开始 preStart+1, 左子树先序结束 (rootIndex-inStart)+preStart
* 左子树中序开始 inStart, 左子树中序结束 rootIndex-1
*/
Node left=createBinaryTree(preOrder,preStart+1,rootIndex-inStart+preStart,inOrder,inStart,rootIndex-1);
/*
* 递归求解右子树:右子树先序开始 preStart+rootIndex-inStart+1, 右子树先序结束 preEnd
* 右子树中序开始 rootIndex+1, 右子树中序结束 inEnd
*/
Node right=createBinaryTree(preOrder,preStart+rootIndex-inStart+1,preEnd,inOrder,rootIndex+1,inEnd);
root.left=left;
root.right=right;
return root;
}
/*
* 获取二叉排序树中两个节点的最近公共父节点,root和两个节点的值(x, y)已知
*/
public static Node getBinSortTreeFather(Node root,int x,int y){
//两个节点最大、最小值,用于比较
int max,min;
max=x>=y?x:y;
min=x<y?x:y;
while(root!=null){
//两个节点在root节点两侧或某个节点是另一个节点的父节点,返回root节点
if(root.data>=min&&root.data<=max)
return root;
//两个节点同在root节点右侧
else if(root.data<min)
root=root.right;
//两个节点同在root节点左侧
else
root=root.left;
}
return null;
}
/*
* 获取二叉树中两个节点的最近公共父节点,root和两个节点的值(x, y)已知
*/
public static Node getFather(Node root,int x,int y){
if(root==null)
return null;
if(root.data==x||root.data==y)
return root;
Node left=getFather(root.left,x,y);//递归遍历root节点左侧
Node right=getFather(root.right,x,y);//递归遍历root节点右侧
if(left!=null&&right!=null)//两个节点分别在root节点的两侧,父节点不是两个节点中的一个
return root;
return left!=null? left:right;//两个节点在root节点的同一侧(左侧或右侧),父节点是两个节点中的一个
}
//判断数值是否在二叉树中
public static boolean isInTree(Node root,int x){
if(root==null)
return false;
if(root.data==x)
return true;
boolean a=false;
boolean b=false;
if(root.left!=null)
a=isInTree(root.left,x);
if(root.right!=null)
b=isInTree(root.right,x);
if(a||b)
return true;
else return false;
}
//节点的最大距离
private static int maxLen=0;
/*
* 递归求解节点的最大距离
*/
public static void findMaxDistance(Node root){
if(root==null)
return;
if(root.left==null)
root.leftMaxDistance=0;
if(root.right==null)
root.rightMaxDistance=0;
if(root.left!=null){
findMaxDistance(root.left);
root.leftMaxDistance=max(root.left.leftMaxDistance,root.left.rightMaxDistance)+1;
}
if(root.right!=null){
findMaxDistance(root.right);
root.rightMaxDistance=max(root.right.leftMaxDistance,root.right.rightMaxDistance)+1;
}
if(root.leftMaxDistance+root.rightMaxDistance>maxLen)
maxLen=root.leftMaxDistance+root.rightMaxDistance;
}
public static int max(int x,int y){
return x>y?x:y;
}
public static void main(String[] args) {
BinSortTree tree=new BinSortTree();
int[] data={2,8,7,4,9,3,1,6,7,5};
tree.buildTree(data);
System.out.print("二叉树中节点的最大距离: ");
findMaxDistance(tree.root);
System.out.print(maxLen);
System.out.println();
System.out.print("最近公共父节点值: ");
System.out.print(getFather(tree.root,3,4).data);
System.out.println();
System.out.print("是否在树中: ");
System.out.print(isInTree(tree.root,11));
System.out.println();
//先序遍历
System.out.print("先序遍历: ");
OrderBinTree.preOrder(tree.root);
System.out.println();
//中序遍历
System.out.print("中序遍历: ");
OrderBinTree.inOrder(tree.root);
System.out.println();
//后序遍历
System.out.print("后序遍历: ");
OrderBinTree.postOrder(tree.root);
System.out.println();
//层次遍历
System.out.print("层次遍历: ");
OrderBinTree.layerOrder(tree.root);
}
}
//二叉树遍历类
class OrderBinTree{
/*
* 先序遍历-->根节点,左子树,右子树(递归实现)
*/
public static void preOrder(Node root){
if(root!=null){
System.out.print(root.data+" ");//输出根节点数值
preOrder(root.left);//左子树
preOrder(root.right);//右子树
}
}
/*
* 中序遍历-->左子树,根节点,右子树(递归实现)
*/
public static void inOrder(Node root){
if(root!=null){
inOrder(root.left);//左子树
System.out.print(root.data+" ");//输出根节点数值
inOrder(root.right);//右子树
}
}
/*
* 后序遍历-->左子树,右子树,根节点(递归实现)
*/
public static void postOrder(Node root){
if(root!=null){
postOrder(root.left);//左子树
postOrder(root.right);//右子树
System.out.print(root.data+" ");//输出根节点数值
}
}
/*
* 层次遍历(采用队列实现)
*/
public static void layerOrder(Node root){
if(root!=null){
Queue<Node> q=new LinkedList<Node>();
q.add(root);
while(!q.isEmpty()){ //当前队列不为空
Node n=q.poll();
System.out.print(n.data+" ");
if(n.left!=null){
q.add(n.left);
}
if(n.right!=null){
q.add(n.right);
}
}
}
}
}