二叉树的java实现

Posted myJavaEE

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的java实现相关的知识,希望对你有一定的参考价值。

import java.util.Arrays;
import java.util.Stack;


// 链式存储的二叉树
public class BSTree {
    private TreeNode root = null;
    public TreeNode getRoot() {
        return root;
    }
    public BSTree(TreeNode root) {
        this.root = root;
    }
    
    public boolean isEmpty() {
        return root == null;
    }

    // 树的高度
    public int height() {
        return TreeNode.height(root);
    }

    // 节点个数
    public int size() {
        return TreeNode.size(root);
    }

    // 返回树中某节点的父节点
    public TreeNode parent(TreeNode element) {
        return (root == null || root == element) ? null : TreeNode.getParent(root, element);
    }

    
    // 定义树的节点
    private static class TreeNode {
        private int data;
        private TreeNode leftChild = null;
        private TreeNode rightChild = null;
        
        public TreeNode(int data) {
            this.data = data;
            this.leftChild = null;
            this.rightChild = null;
        }
        
        public static TreeNode getParent(TreeNode subTree, TreeNode element) {
            if (subTree == null)
                return null;
            if (subTree.leftChild == element || subTree.rightChild == element)
                return subTree;
            TreeNode p = null;
            // 递归左右子树
            if ((p = getParent(subTree.leftChild, element)) != null)
                return p;
            else
                return getParent(subTree.rightChild, element);
        }

        public static TreeNode getLeftChildNode(TreeNode element) {
            return (element != null) ? element.leftChild : null;
        }

        public static TreeNode getRightChildNode(TreeNode element) {
            return (element != null) ? element.rightChild : null;
        }
        
        public static 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);
            }
        }
        
        public static int size(TreeNode subTree) {
            if (subTree == null) {
                return 0;
            } else {
                return 1 + size(subTree.leftChild) + size(subTree.rightChild);
            }
        }
        
        // 在释放某个结点前, 该结点的左右子树应该已经释放, 所以应该采用后续遍历
        public static void destroySubTree(TreeNode subTree) {
            // 删除根为subTree的子树
            if (subTree != null) {
                destroySubTree(subTree.leftChild);
                destroySubTree(subTree.rightChild);
                // 删除根结点
                subTree = null;
            }
        }
        
        
        public static void visted(TreeNode subTree) {
            System.out.println("data: " + subTree.data);
        }
        
        // 前序遍历
        public static void preOrder(TreeNode subTree) {
            if (subTree != null) {
                visted(subTree);
                preOrder(subTree.leftChild);
                preOrder(subTree.rightChild);
            }
        }

        // 中序遍历
        public static void inOrder(TreeNode subTree) {
            if (subTree != null) {
                inOrder(subTree.leftChild);
                visted(subTree);
                inOrder(subTree.rightChild);
            }
        }

        // 后续遍历
        public static void postOrder(TreeNode subTree) {
            if (subTree != null) {
                postOrder(subTree.leftChild);
                postOrder(subTree.rightChild);
                visted(subTree);
            }
        }
        
        // 前序遍历的非递归实现
        public static void nonRecPreOrder(TreeNode subTree) {
            Stack<TreeNode> stack = new Stack<TreeNode>();
            TreeNode node = subTree;
            while (node != null || stack.size() > 0) {
                if (node != null) {
                    visted(node);
                    stack.push(node);
                    node = node.leftChild;
                } else {
                    node = stack.pop();
                    node = node.rightChild;
                }
            }
        }

        // 中序遍历的非递归实现
        public static void nonRecInOrder(TreeNode subTree) {
            Stack<TreeNode> stack = new Stack<TreeNode>();
            TreeNode node = subTree;
            while (node != null || stack.size() > 0) {
                // 存在左子树
                if (node != null) {
                    stack.push(node);
                    node = node.leftChild;
                }
                else {
                    node = stack.pop();
                    visted(node);
                    node = node.rightChild;
                }
            }
        }

        // 后序遍历的非递归实现
        public static void nonRecPostOrder(TreeNode subTree) {
            if (null == subTree) { //为确保下面循环至少执行一次
                return;  
            }
            Stack<TreeNode> stack = new Stack<TreeNode>();
            TreeNode node = subTree;
            TreeNode lastVisited = subTree;
            while (true) {
                // 左路入栈
                while (node.leftChild != null) {
                    stack.push(node);    //第一次压栈, 为了访问左路后退出
                    node = node.leftChild;
                }
                // 连续处理从右路返回的节点
                while (node.rightChild == null || node.rightChild == lastVisited) {
                    // 访问并纪录本次访问节点
                    visted(node);
                    lastVisited = node;
                    if (stack.empty()) {
                        return;
                    }
                    node = stack.pop();
                }
                // 处理从左路返回的节点
                stack.push(node);  // 第二次压栈, 为了访问右路后退出
                node = node.rightChild;
            }
        }
    }
    
    
    // 二叉搜索树
    public void add(int data) {
        add(root, data);
    }
    
    public boolean contains(int data) {
        return contains(root, data);
    }
    
    public int minValue() {
        return findMin(root).data;
    }
    
    public int maxValue() {
        return findMax(root).data;
    }
    
    private TreeNode findMin(TreeNode subTree) {
        if (null == subTree) {
            return null;
        } else if (null == subTree.leftChild) {
            return subTree;
        }
        return findMin(subTree.leftChild);
    }

    private TreeNode findMax(TreeNode subTree) {
        if (null != subTree) {
            while (null != subTree.rightChild) {
                subTree = subTree.rightChild;
            }
        }
        return subTree;
    }
    // 添加节点进搜索树
    private TreeNode add(TreeNode subTree, int data) {
        if (null == subTree) {
            return new TreeNode(data);
        } else if (data > subTree.data) {
            subTree.rightChild = add(subTree.rightChild, data);
            return subTree;
        } else if (data < subTree.data) {
            subTree.leftChild = add(subTree.leftChild, data);
            return subTree;
        } // 这里限定搜索树中元素不重复
        return subTree;
    }

    private boolean contains(TreeNode subTree, int data) {
        if (null == subTree) {
            return false;
        } else if (data > subTree.data) {
                return contains(subTree.rightChild, data);
        } else if (data < subTree.data){
                return contains(subTree.leftChild, data);
        } else {
            return true;
        }
    }
    
    private TreeNode remove(TreeNode subTree, int data) {
        if (null == subTree) {
            return null;
        } else if (data > subTree.data) {
            return remove(subTree.rightChild, data);
        } else if (data < subTree.data) {
            return remove(subTree.leftChild, data);
        } else if (null == subTree.leftChild || null == subTree.rightChild) {  //节点匹配, 只有一个孩子或没有孩子
            return (subTree.leftChild != null) ? subTree.leftChild : subTree.rightChild; 
        } else {      //节点匹配, 有两个孩子
            subTree.data = findMin(subTree.rightChild).data;
            subTree.rightChild = remove(subTree.rightChild, subTree.data);
            return subTree;
        }
    }
    
    // 测试
    public static void main(String[] args) {
        // 创建树
        int[] values = new int[8];
        for (int i = 0; i < 8; i++) {
            int num = (int) (Math.random() * 15);
            if (!checkDup(values, num))
                values[i] = num;
            else
                i--;
        }
        System.out.println("generate Nums:" + Arrays.toString(values));

        BSTree tree = new BSTree(new TreeNode(values[0]));
        for (int i = 1; i < values.length; i++) {
            tree.add(values[i]);
        }

        System.out.println("树高: " + TreeNode.height(tree.getRoot()));
        System.out.println("树大小: " + TreeNode.size(tree.getRoot()));
        System.out.println("前序遍历:");
        TreeNode.nonRecPreOrder(tree.getRoot());
        System.out.println("中序遍历:");
        TreeNode.nonRecInOrder(tree.getRoot());
        System.out.println("后序遍历:");
        TreeNode.nonRecPostOrder(tree.getRoot());
    }
    private static boolean checkDup(int[] arr, int value) {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == value)
                return true;
        }
        return false;
    }
    
}

 

以上是关于二叉树的java实现的主要内容,如果未能解决你的问题,请参考以下文章

Java实现二叉树的创建和遍历操作(有更新)

Java实现二叉树的创建和遍历操作(有更新)

java实现线索化二叉树的前序中序后续的遍历(完整代码)

java实现二叉树的构建以及3种遍历方法

利用JAVA语言,将二叉树封装在一个类中,要求实现二叉树的构造,并实现二叉树的遍历操作。

数据结构 Java 版二叉树的实现(超多图超详解)