zoukankan      html  css  js  c++  java
  • JAVA实现通过中序遍历和后序遍历序列建树,并求树的高度,用层次遍历做验证

    作为例子的树长这样:

    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<Character> posOrder = Arrays.asList('B', 'A', 'E', 'D', 'C');
            List<Character> inOrder = Arrays.asList('A', 'B', 'C', 'D', 'E');
            System.out.println("通过");
            System.out.println("中序序列:"+inOrder);
            System.out.println("后序序列:"+posOrder);
            System.out.println("成功构建二叉树,其先序遍历为:");
    
            //建树
            MyBinarySearchTree<Character> 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<E extends Comparable<? super E>> {
        public TreeNode root;
        private int size;
        private int high;
    
        private class TreeNode<E> {
            TreeNode left;
            TreeNode right;
            E value;
    
            public TreeNode(E value) {
                this.value = value;
            }
        }
    
        //中序、后序遍历建树方法
        public static <T extends Comparable<? super T>> MyBinarySearchTree buildTree(List<T> inOrder, List<T> posOrder) {
            MyBinarySearchTree<T> tree = new MyBinarySearchTree<>();
            tree.size = 0;
            tree.root = tree.build(inOrder, posOrder);
            return tree;
        }
    
        private TreeNode build(List<E> inOrder, List<E> 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<E> subLeftInOrder = inOrder.subList(0, index); //实际[0,index-1];
            List<E> subLeftPosOrder = posOrder.subList(0, index);
            node.left = build(subLeftInOrder, subLeftPosOrder);
    
            List<E> subRightInOrder = inOrder.subList(index + 1, posOrder.size());//可不是size-1 ; size 是树的大小信息...;左闭右开
            List<E> 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<List<E>> levelOrder(){
            List<List<E>> res = new ArrayList<>();
            if(root == null) return null;
    
            Queue<TreeNode> queue = new LinkedList<>(); //queue 必须用LinkedList,才有继承Queue接口
            queue.add(root);
            while(!queue.isEmpty()){
                int count = queue.size();
                List<E> 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<E> preOrder() {
            List<E> list = new ArrayList<>();
            preOrder(root, list);
            return list;
        }
    
        private void preOrder(TreeNode scan, List<E> list) {
    
            if (scan == null) return;
    
            list.add((E) scan.value);
            preOrder(scan.left, list);
            preOrder(scan.right, list);
    
        }
    
    
    }
    

      在IDEA中运行结果:

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

  • 相关阅读:
    『水晶报表』实现打印
    C#水晶报表教程
    C#
    C# 跨线程调用控件
    SQL中DateTime转换成Varchar样式
    解决SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问的方法
    配置JAVA的环境变量
    lucene3.0_IndexSearcher排序
    tomcat如何配置环境变量
    无法启动DISTRIBUTED TRANSACTION COORDINATOR解决方法
  • 原文地址:https://www.cnblogs.com/debug-the-heart/p/13358374.html
Copyright © 2011-2022 走看看