Java实现二叉树

关于此二叉树

  • 此版本的二叉树存在一些缺陷
    • 没有实现对高度、规模更新
    • 树节点采用私有内部类形式,会造成一些操作上的麻烦。
  • 先序遍历详解
  • 中序遍历详解

二叉树的实现

import java.util.ArrayList;
import java.util.LinkedList;

@SuppressWarnings("unused")
public class BinaryTree<E> {
    private Node<E> root;

    public BinaryTree(){
        root = null;
    }
    public BinaryTree(E e){
        root = new Node<E>();
        root.e = e;
    }

    //判空
    public boolean empty(){
        return root==null?true:false;
    }
    //返回根节点
    public Node<E> getRoot() {
        return root;
    }
    //插入根节点
    public Node<E> inserAsRoot(E e) {
        // assert root == null;
        root = new Node<E>(e,null,null,null);
        return root;
    } 
    //将e作为x的左孩子插入
    public Node<E> inserAsLC(Node<E> x,E e){
        // assert x.lc == null;
        return x.inserAsLC(e);
    }
    //将E作为x的右孩子插入
    public Node<E> inserAsRC(Node<E> x,E e){
        // assert x.rc == null;
        return x.inserAsRC(e);
    }
    //按照先序插入x的后代
    public void inserPre(Node<E> x,E[] arr) {
        // assert x != null;
        LinkedList<Node<E>> queue = new LinkedList<Node<E>>();
        queue.add(x);
        for(int i = 0 ; i < arr.length ; i++) {
            x = queue.peek();
            if(i % 2 == 0) {
                queue.add(queue.peek().inserAsLC(arr[i]));
                queue.peekLast().parent = x; //建立父链接
            } else {
                queue.add(queue.poll().inserAsRC(arr[i]));
                queue.peekLast().parent = x;
            }   
        }
        size = arr.length;
    }
    //先序遍历迭代版
    public ArrayList<E> travPre() {
        return root.travPre();
    }
    //中序遍历
    public ArrayList<E> travIn() {
        return root.travIn();
    }
    //后序遍历
    public ArrayList<E> travPost() {
        return root.travPost();
    }
    //层次遍历
    public ArrayList<E> travLevel(){
        return root.travLevel();
    }
    //树节点类
    private static class Node<E> {      
        Node<E> lc;
        Node<E> rc;
        Node<E> parent;
        E e;
        int h;
        Node(E e,Node<E> lc,Node<E> rc,Node<E> parent){
            this.e = e;
            this.lc = lc;
            this.rc = rc;
            this.parent = parent;
            h  = 0;
        }
        Node(){
        }
        //作为当前节点的左孩子插入新节点
        public Node<E> inserAsLC(E e) {
            // assert lc == null;
            lc = new Node<E>(e,null,null,this);
            return lc;
        }
        //作为当前节点的右孩子插入新节点
        public Node<E> inserAsRC(E e) {
            // assert rc == null;
            rc = new Node<E>(e,null,null,this);
            return rc;
        }
        //子树先序遍历
        public ArrayList<E> travPre() {
            LinkedList<Node<E>> stack = new LinkedList<Node<E>>();//辅助栈
            ArrayList<E> al = new ArrayList<E>();
            Node<E> x = this;
            while(true) {
                visitAlongLeftBreanch(x,al,stack);
                if( stack.isEmpty())
                    return al;
                x = stack.pop();
            }
        }
        //子树中序遍历
        public ArrayList<E> travIn() {
            LinkedList<Node<E>> stack = new LinkedList<Node<E>>();//辅助栈
            ArrayList<E> al = new ArrayList<E>();
            Node<E> x = this;
            while(true) {
                goAlongLeftBreanch(x,stack);
                if(stack.isEmpty())
                    return al;
                x = stack.pop();
                al.add(x.e);
                x = x.rc;
            }
        }
        //子树后序遍历
        public ArrayList<E> travPost() {
            LinkedList<Node<E>> stack = new LinkedList<Node<E>>();//辅助栈
            ArrayList<E> al = new ArrayList<E>();
            Node<E> x = this;
            if(x != null)
                stack.push(x);
            while(!stack.isEmpty()) {
                if(stack.peek() != x.parent)//若栈顶非当前节点之父,则必为其右兄,此时需
                    goToHLVFL(stack);//在以其右兄为根的子树中,找到左分支最深的节点
                x = stack.pop();
                al.add(x.e);
            }
            return al;
        }
        //
        public ArrayList<E> travLevel(){
            LinkedList<Node<E>> queue = new LinkedList<Node<E>>();//辅助队列
            ArrayList<E> al = new ArrayList<E>();
            Node<E> x = this;
            queue.add(x);
            while(!queue.isEmpty()) {
                x = queue.poll();
                al.add(x.e);
                if(x.lc != null)
                    queue.add(x.lc);
                if(x.rc != null)
                    queue.add(x.rc);
            }
            return al;
        }
        private void visitAlongLeftBreanch(Node<E> x,ArrayList<E> al,LinkedList<Node<E>> s) {
            while(x != null) {
                al.add(x.e);
                s.push(x.rc); //读取左孩子得值,将右孩子压入栈
                x = x.lc;
            }
        }
        private void goAlongLeftBreanch(Node<E> x,LinkedList<Node<E>> s) {
            while(x != null) {
                s.push(x); //将左分支压入栈
                x = x.lc;
            }
        }
        private void goToHLVFL(LinkedList<Node<E>> s) {
            Node<E> x;              
            while(s.peek() != null) {
                x = s.peek();
                //按照先右后左的顺序压入栈
                if(x.lc != null) {
                    if(x.rc != null) {
                        s.push(x.rc);
                    }
                    s.push(x.lc);
                } else {
                    s.push(null);
                }
            }
            s.pop();
        }
    }
}

二叉树实现的测试函数

public static void main(String[] args) {
        BinaryTree<String>  bt = new BinaryTree<String>();
        ArrayList<String> al;
        StringBuffer sb = new StringBuffer();
        String[] s = {"L1","T1","L2","T2","L2-1","T2-1"};
        String[] s1 = {"b","f","a","c","e"};
        String[] s2 = {"c","f","a","b","d","e"};
        bt.inserAsRoot("L0");
        bt.inserPre(bt.getRoot(),s);
        al = bt.travPre();
        for(int i = 0 ; i < al.size() ; i++) {
            sb.append(al.get(i)+",");
        }       
        System.out.println("先序遍历:"+sb.toString());

        sb.delete(0,sb.length());

        al = bt.travLevel();
        for(int i = 0 ; i < al.size() ; i++) {
            sb.append(al.get(i)+",");
        }       
        System.out.println("层次遍历:"+sb.toString());

        sb.delete(0,sb.length());

        bt.inserAsRoot("d");
        bt.inserPre(bt.getRoot(),s1);
        al = bt.travIn();
        for(int i = 0 ; i < al.size() ; i++) {
            sb.append(al.get(i)+",");
        }       
        System.out.println("中序遍历:"+sb.toString());

        sb.delete(0,sb.length());

        bt.inserAsRoot("g");
        bt.inserPre(bt.getRoot(),s2);
        al = bt.travPost();
        for(int i = 0 ; i < al.size() ; i++) {
            sb.append(al.get(i)+",");
        }
        System.out.println("后序遍历:"+sb.toString());
    }

测试结果

树的结构
            L0
    L1              T1
L2      T2      L2-1    T2-1
* 先序遍历:L0,L1,L2,T2,T1,L2-1,T2-1,
* 层次遍历:L0,L1,T1,L2,T2,L2-1,T2-1,
树的结构
            d
    b             f
a      e     e    
* 中序遍历:a,b,c,d,e,f,
树的结构
            g
    c               f
a      b        d       e
* 后序遍历:a,b,c,d,e,f,g,

参考资料

  • 数据结构(c++语言版)(第三版)
    • 邓俊辉 编著
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值