作为例子的树长这样:
package bstpractice;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BstTest {
public static void main(String args[]){
//step1,先根据中序,后序序列建树
List posOrder = Arrays.asList('B', 'A', 'E', 'D', 'C');
List inOrder = Arrays.asList('A', 'B', 'C', 'D', 'E');
System.out.println("通过");
System.out.println("中序序列:"+inOrder);
System.out.println("后序序列:"+posOrder);
System.out.println("成功构建二叉树,其先序遍历为:");
//建树
MyBinarySearchTree myBST =MyBinarySearchTree.buildTree(inOrder,posOrder);
//先序遍历
// System.out.println("先序遍历结果:");
System.out.println(myBST.preOrder());
System.out.println("高度是:"+myBST.getHigh());
System.out.println("通过其层次遍历:");
System.out.println(myBST.levelOrder());
System.out.println("可知正确");
}
}
package bstpractice;
import sun.reflect.generics.tree.Tree;
import java.util.*;
public class MyBinarySearchTree> {
public TreeNode root;
private int size;
private int high;
private class TreeNode {
TreeNode left;
TreeNode right;
E value;
public TreeNode(E value) {
this.value = value;
}
}
//中序、后序遍历建树方法
public static > MyBinarySearchTree buildTree(List inOrder, List posOrder) {
MyBinarySearchTree tree = new MyBinarySearchTree<>();
tree.size = 0;
tree.root = tree.build(inOrder, posOrder);
return tree;
}
private TreeNode build(List inOrder, List posOrder) {
//边界条件
if (posOrder.isEmpty() || posOrder == null) return null;
//if(inOrder.isEmpty()|| inOrder == null) return null;
E e = posOrder.get(posOrder.size() - 1);//根元素
int index = inOrder.indexOf(e);//得到划分位置和 左子树子序列长度信息,是index!!不是index-1
TreeNode node = new TreeNode(e);
//inOrder(0,index-1);index;(index+1,size-1)
//posOrder(0,0+index-1);(index,size-2);size-1;
//subList【 )!!! subList【 )!!! subList【 )!!! subList【 )!!!
List subLeftInOrder = inOrder.subList(0, index); //实际[0,index-1];
List subLeftPosOrder = posOrder.subList(0, index);
node.left = build(subLeftInOrder, subLeftPosOrder);
List subRightInOrder = inOrder.subList(index + 1, posOrder.size());//可不是size-1 ; size 是树的大小信息...;左闭右开
List subRightPosOrder = posOrder.subList(index, posOrder.size() - 1);
node.right = build(subRightInOrder, subRightPosOrder);
return node;
}
//用栈实现层次遍历,实现方式有多种,就用上课老师讲的反式实现吧;大致思路就是用一个size记录一层的大小,集中手机层次的结点
/* 算法:
1.入栈根结点
2.队列空?
不是:
a.查看队列的大小,记为size;
b.循环控制出队列size个元素
1).出结点并访问(添加到list)
2).出结点有左子树?有左结点入队列
3).出结点有右子树?有右节点入队列
返回回size个元素的Linkedlist到res中
c.回到2
是:返回res列表(List),res的元素是Linkedlist
* */
public List> levelOrder(){
List> res = new ArrayList<>();
if(root == null) return null;
Queue queue = new LinkedList<>(); //queue 必须用LinkedList,才有继承Queue接口
queue.add(root);
while(!queue.isEmpty()){
int count = queue.size();
List oneLevelList = new ArrayList<>();
while(count>0){
TreeNode p = queue.remove();
oneLevelList.add((E) p.value);
count --;
if(p.left!=null) queue.add(p.left);
if(p.right!=null) queue.add(p.right);
}
res.add(oneLevelList);
}
return res;
}
//返回高度的方法
public int getHigh(){
if(root == null) return 0;
return high = high(root);
}
private int high(TreeNode p){ //求树的高度,等于左子树和右子树高度之中较大的那个
int leftH =0;
int rightH =0;
//没有子树了
if(p.left == null && p.right == null){
return 1;
}
//有左子树,递归求左子树给高度
if(p.left !=null) {
leftH = high(p.left)+1;
}
//有右子树,递归求右子树高度
if(p.right != null){
rightH = high(p.right)+1;
}
return leftH >= rightH ? leftH : rightH ;
}
//先实现一个递归先序遍历,NLR
public List preOrder() {
List list = new ArrayList<>();
preOrder(root, list);
return list;
}
private void preOrder(TreeNode scan, List list) {
if (scan == null) return;
list.add((E) scan.value);
preOrder(scan.left, list);
preOrder(scan.right, list);
}
}
在IDEA中运行结果:
注意事项:在实现建树的时候,要记得subList的参数是左闭右开的
来源:https://www.cnblogs.com/debug-the-heart/p/13358374.html