java建树_JAVA实现通过中序遍历和后序遍历序列建树,并求树的高度,用层次遍历做验证...

作为例子的树长这样:

6c1555302777729326ca3efa0910d9ec.png

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中运行结果:

6c1555302777729326ca3efa0910d9ec.png

注意事项:在实现建树的时候,要记得subList的参数是左闭右开的

来源:https://www.cnblogs.com/debug-the-heart/p/13358374.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值