java二叉树怎么实现?简单二叉树实现

二叉树是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树的形式,因此二叉树显得特别重要。那java二叉树怎么实现?下面来我们就来给大家讲解一下这方面的内容。

首先创建一棵二叉树如下图,然后对这颗二叉树进行遍历操作(遍历操作的实现分为递归实现和非递归实现),同时还提供一些方法如获取双亲结点、获取左孩子、右孩子等。

java二叉树怎么实现?简单二叉树实现.jpg

Java实现代码:

import java.util.Stack;
/**
* 二叉树的链式存储
*/
public class BinaryTree
{
    /**
    * 二叉树的节点数据结构
    */
    private class TreeNode
    {
        /**
        * 序号
        */
        private int key = 0;
        /**
        * 值
        */
        private String data = null;
        private boolean isVisted = false;
        /**
        * 左儿子节点
        */
        private TreeNode leftChild = null;
        /**
        * 右儿子节点
        */
        private TreeNode rightChild = null;
        /**
        * 默认构造方法
        */
        public TreeNode()
        {}
        /**
        * @param key 层序编码
        * @param data 数据域
        */
        public TreeNode(int key, String data)
        {
            this.key = key;
            this.data = data;
            this.leftChild = null;
            this.rightChild = null;
        }
    }
    private TreeNode root = null;
    /**
    * 默认构造方法
    * 指定根节点
    */
    public BinaryTree()
    {
        root = new TreeNode(1, "rootNode(A)");
    }
    /**
    * 创建一棵二叉树
    *
    *           A
    *     B          C
    *  D     E            F
    *
    * @param root
    * @author WWX
    */
    public void createBinTree(TreeNode root)
    {
        TreeNode newNodeB = new TreeNode(2, "B");
        TreeNode newNodeC = new TreeNode(3, "C");
        TreeNode newNodeD = new TreeNode(4, "D");
        TreeNode newNodeE = new TreeNode(5, "E");
        TreeNode newNodeF = new TreeNode(6, "F");
        newNodeC.rightChild = newNodeF; //root.rightChild.rightChild=newNodeF;
        newNodeB.leftChild = newNodeD; //root.leftChild.leftChild=newNodeD;
        newNodeB.rightChild = newNodeE; //root.leftChild.rightChild=newNodeE;
        root.leftChild = newNodeB;
        root.rightChild = newNodeC;
    }
    /**
    * 判断跟节点是否为空
    * @return 返回根节点是否为空
    */
    public boolean isEmpty()
    {
        return root == null;
    }
    //树的高度
    public int height()
    {
        return height(root);
    }
    //节点个数
    public int size()
    {
        return size(root);
    }
    /**
    * 计算二叉树节点的高度
    * @param subTree 节点
    * @return 节点高度
    */
    private int height(TreeNode subTree)
    {
        if (subTree == null)
            return 0; //递归结束:空树高度为0
        else
        {
            int i = height(subTree.leftChild);
            int j = height(subTree.rightChild);
            return (i < j) ? (j + 1) : (i + 1);
        }
    }
    /**
    * 计算节点大小
    * @param subTree 节点
    * @return 节点大小
    */
    private int size(TreeNode subTree)
    {
        if (subTree == null)
        {
            return 0;
        }
        else
        {
            return 1 + size(subTree.leftChild) + size(subTree.rightChild);
        }
    }
    //返回双亲结点
    public TreeNode parent(TreeNode element)
    {
        return (root == null || root == element) ? null : parent(root, element);
    }
    public TreeNode parent(TreeNode subTree, TreeNode element)
    {
        if (subTree == null)
            return null;
        if (subTree.leftChild == element || subTree.rightChild == element)
            //返回父结点地址
            return subTree;
        TreeNode p;
        //现在左子树中找,如果左子树中没有找到,才到右子树去找
        if ((p = parent(subTree.leftChild, element)) != null)
            //递归在左子树中搜索
            return p;
        else
            //递归在右子树中搜索
            return parent(subTree.rightChild, element);
    }
    public TreeNode getLeftChildNode(TreeNode element)
    {
        return (element != null) ? element.leftChild : null;
    }
    public TreeNode getRightChildNode(TreeNode element)
    {
        return (element != null) ? element.rightChild : null;
    }
    public TreeNode getRoot()
    {
        return root;
    }
    //在释放某个结点时,该结点的左右子树都已经释放,
    //所以应该采用后续遍历,当访问某个结点时将该结点的存储空间释放
    public void destroy(TreeNode subTree)
    {
        //删除根为subTree的子树
        if (subTree != null)
        {
            //删除左子树
            destroy(subTree.leftChild);
            //删除右子树
            destroy(subTree.rightChild);
            //删除根结点
            subTree = null;
        }
    }
    public void traverse(TreeNode subTree)
    {
        System.out.println("key:" + subTree.key + "--name:" + subTree.data);;
        traverse(subTree.leftChild);
        traverse(subTree.rightChild);
    }
    //前序遍历
    public void preOrder(TreeNode subTree)
    {
        if (subTree != null)
        {
            visted(subTree);
            preOrder(subTree.leftChild);
            preOrder(subTree.rightChild);
        }
    }
    //中序遍历
    public void inOrder(TreeNode subTree)
    {
        if (subTree != null)
        {
            inOrder(subTree.leftChild);
            visted(subTree);
            inOrder(subTree.rightChild);
        }
    }
    //后续遍历
    public void postOrder(TreeNode subTree)
    {
        if (subTree != null)
        {
            postOrder(subTree.leftChild);
            postOrder(subTree.rightChild);
            visted(subTree);
        }
    }
    //前序遍历的非递归实现
    public void nonRecPreOrder(TreeNode p)
    {
        Stackstack = new Stack();
        TreeNode node = p;
        while (node != null || stack.size() > 0)
        {
            while (node != null)
            {
                visted(node);
                stack.push(node);
                node = node.leftChild;
            }
            while (stack.size() > 0)
            {
                node = stack.pop();
                node = node.rightChild;
            }
        }
    }
    //中序遍历的非递归实现
    public void nonRecInOrder(TreeNode p)
    {
        Stackstack = new Stack();
        TreeNode node = p;
        while (node != null || stack.size() > 0)
        {
            //存在左子树
            while (node != null)
            {
                stack.push(node);
                node = node.leftChild;
            }
            //栈非空
            if (stack.size() > 0)
            {
                node = stack.pop();
                visted(node);
                node = node.rightChild;
            }
        }
    }
    //后序遍历的非递归实现
    public void noRecPostOrder(TreeNode p)
    {
        Stackstack = new Stack();
        TreeNode node = p;
        while (p != null)
        {
            //左子树入栈
            for (; p.leftChild != null; p = p.leftChild)
            {
                stack.push(p);
            }
            //当前结点无右子树或右子树已经输出
            while (p != null && (p.rightChild == null || p.rightChild == node))
            {
                visted(p);
                //纪录上一个已输出结点
                node = p;
                if (stack.empty())
                    return;
                p = stack.pop();
            }
            //处理右子树
            stack.push(p);
            p = p.rightChild;
        }
    }
    public void visted(TreeNode subTree)
    {
        subTree.isVisted = true;
        System.out.println("key:" + subTree.key + "--name:" + subTree.data);;
    }
    //测试
    public static void main(String[] args)
    {
        BinaryTree bt = new BinaryTree();
        bt.createBinTree(bt.root);
        System.out.println("the size of the tree is " + bt.size());
        System.out.println("the height of the tree is " + bt.height());
        System.out.println("*******(前序遍历)[ABDECF]遍历*****************");
        bt.preOrder(bt.root);
        System.out.println("*******(中序遍历)[DBEACF]遍历*****************");
        bt.inOrder(bt.root);
        System.out.println("*******(后序遍历)[DEBFCA]遍历*****************");
        bt.postOrder(bt.root);
        System.out.println("***非递归实现****(前序遍历)[ABDECF]遍历*****************");
        bt.nonRecPreOrder(bt.root);
        System.out.println("***非递归实现****(中序遍历)[DBEACF]遍历*****************");
        bt.nonRecInOrder(bt.root);
        System.out.println("***非递归实现****(后序遍历)[DEBFCA]遍历*****************");
        bt.noRecPostOrder(bt.root);
    }
}

执行结果为:

the size of the tree is 6
the height of the tree is 3 **
    ** ** * (前序遍历)[ABDECF] 遍历 ** ** ** ** ** ** ** ** * key: 1--name: rootNode(A) key: 2--name: Bkey: 4--name: Dkey: 5--name: Ekey: 3--name: Ckey: 6--name: F **
    ** ** * (中序遍历)[DBEACF] 遍历 ** ** ** ** ** ** ** ** * key: 4--name: Dkey: 2--name: Bkey: 5--name: Ekey: 1--name: rootNode(A) key: 3--name: Ckey: 6--name: F **
    ** ** * (后序遍历)[DEBFCA] 遍历 ** ** ** ** ** ** ** ** * key: 4--name: Dkey: 5--name: Ekey: 2--name: Bkey: 6--name: Fkey: 3--name: Ckey: 1--name: rootNode(A) **
    * 非递归实现 ** ** (前序遍历)[ABDECF] 遍历 ** ** ** ** ** ** ** ** * key: 1--name: rootNode(A) key: 2--name: Bkey: 4--name: Dkey: 3--name: Ckey: 6--name: F **
    * 非递归实现 ** ** (中序遍历)[DBEACF] 遍历 ** ** ** ** ** ** ** ** * key: 4--name: Dkey: 2--name: Bkey: 5--name: Ekey: 1--name: rootNode(A) key: 3--name: Ckey: 6--name: F **
    * 非递归实现 ** ** (后序遍历)[DEBFCA] 遍历 ** ** ** ** ** ** ** ** * key: 4--name: Dkey: 5--name: Ekey: 2--name: Bkey: 6--name: Fkey: 3--name: Ckey: 1--name: rootNode(A)

java二叉树是非常重要的,它相关的每一个知识点,java人员都要熟练的运用,最后大家如果想要了解更多java常见问题知识,敬请关注奇Q工具网。

推荐阅读:

java在哪里编程?java实用编程工具

java大厂面试经验有哪些?附java大厂面试题

java创建对象new方法是什么?java创建对象方法有哪些?