• 二叉树基本操作


    树model

    package com.sly.uploadfile.algorithm;
    
    /**
     * Created by fmgao on 2019/7/24.
     */
    public class TreeNode01<T> {
        T value;
        TreeNode01<T> leftChild;
        TreeNode01<T> rightChild;
    
        TreeNode01() {
        }
    
        TreeNode01(T value) {
            this.value = value;
        }
    
        /**
         * 增加左子节点
         *
         * @param value
         */
        public void addLeft(T value) {
            TreeNode01<T> leftChild = new TreeNode01<T>();
            this.leftChild = leftChild;
    
        }
    
        /**
         * 增加右子节点
         *
         * @param value
         */
        public void addRight(T value) {
            TreeNode01<T> rightChild = new TreeNode01<>();
            this.rightChild = rightChild;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof TreeNode01)) {
                return false;
            }
            return this.value.equals(((TreeNode01<?>) obj).value);
        }
    
        @Override
        public int hashCode() {
            return this.value.hashCode();
        }
    
        @Override
        public String toString() {
            return this.value == null ? "" : this.value.toString();
        }
    }

    树的基本操作

    package com.sly.uploadfile.algorithm;
    
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Queue;
    
    /**
     * Created by fmgao on 2019/7/24.
     */
    public class TreeNodeTools {
    
        /**
         * 判断树种节点个数
         *
         * @param root
         * @param <T>
         * @return
         */
        public static <T> int getTreeNum(TreeNode01<T> root) {
            if (root == null) {
                return 0;
            }
            return getTreeNum(root.leftChild) + getTreeNum(root.rightChild) + 1;
        }
    
        /**
         * 判断树的深度
         *
         * @param root
         * @param <T>
         * @return
         */
        public static <T> int getTreeDepth(TreeNode01<T> root) {
            if (root == null) {
                return 0;
            }
            int leftDepth = getTreeDepth(root.leftChild) + 1;
            int rightDepth = getTreeDepth(root.rightChild) + 1;
            return Math.max(leftDepth, rightDepth);
        }
    
        /**
         * 前序遍历
         *
         * @param root
         * @param <T>
         */
        public static <T> void preOrderTravel(TreeNode01<T> root) {
            if (root == null) {
                return;
            }
            visitNode(root);
            preOrderTravel(root.leftChild);
            preOrderTravel(root.rightChild);
    
        }
    
        /**
         * 中序遍历
         *
         * @param root
         * @param <T>
         */
        public static <T> void midOrderTravel(TreeNode01<T> root) {
            if (root == null) {
                return;
            }
            midOrderTravel(root.leftChild);
            visitNode(root);
            midOrderTravel(root.rightChild);
    
        }
    
        /**
         * 后续遍历
         *
         * @param root
         * @param <T>
         */
        public static <T> void backOrderTravel(TreeNode01<T> root) {
            if (root == null) {
                return;
            }
            backOrderTravel(root.leftChild);
            backOrderTravel(root.rightChild);
            visitNode(root);
    
        }
    
        /**
         * 访问node节点
         *
         * @param node01
         * @param <T>
         */
        public static <T> void visitNode(TreeNode01<T> node01) {
            System.out.println(node01.value + "	");
        }
    
        /**
         * 分层遍历
         *
         * @param root
         * @param <T>
         */
        public static <T> void levelTravel(TreeNode01<T> root) {
            Queue<TreeNode01<T>> q = new LinkedList<TreeNode01<T>>();
            q.offer(root);
            while (!q.isEmpty()) {
                TreeNode01<T> tmp = q.poll();
                visitNode(tmp);
                if (tmp.leftChild != null) {
                    q.offer(tmp.leftChild);
                }
                if (tmp.rightChild != null) {
                    q.offer(tmp.rightChild);
                }
            }
    
        }
    
        /**
         * 求第K层节点个数
         *
         * @param root
         * @param k
         * @param <T>
         * @return
         */
        public static <T> int getNumForKLevel(TreeNode01<T> root, int k) {
            if (root == null || k < 1) {
                return 0;
            }
            if (k == 1) {
                return 1;
            }
            int leftNum = getNumForKLevel(root.leftChild, k - 1);
            int rightNum = getNumForKLevel(root.rightChild, k - 1);
            return leftNum + rightNum;
        }
    
        /**
         * 求二叉树种叶子节点的个数
         *
         * @param root
         * @param <T>
         * @return
         */
        public static <T> int getLeafNum(TreeNode01<T> root) {
            if (root == null) {
                return 0;
            }
            if (root.leftChild == null && root.rightChild == null) {
                return 1;
            }
            int leftNum = getLeafNum(root.leftChild);
            int rightNum = getLeafNum(root.rightChild);
            return leftNum + rightNum;
        }
    
        /**
         * 交换根节点的左右子树
         *
         * @param root
         * @param <T>
         * @return
         */
        public static <T> TreeNode01<T> exchange(TreeNode01<T> root) {
            if (root == null) {
                return null;
            }
            TreeNode01<T> left = exchange(root.leftChild);
            TreeNode01<T> right = exchange(root.rightChild);
            root.leftChild = right;
            root.rightChild = left;
            return root;
        }
    
        /**
         * 查看node是否是root的节点
         *
         * @param root
         * @param node
         * @param <T>
         * @return
         */
        public static <T> boolean nodeIsChild(TreeNode01<T> root, TreeNode01<T> node) {
            if (root == null || node == null) {
                return false;
            }
            if (root == node) {
                return true;
            }
            boolean isFind = nodeIsChild(root.leftChild, node);
            if (!isFind) {
                isFind = nodeIsChild(root.rightChild, node);
            }
            return isFind;
        }
    
        /**
         * 返回lNode 和 rNode 以root为根节点的公共父节点
         *
         * @param root
         * @param lNode
         * @param rNode
         * @param <T>
         * @return
         */
        public static <T> TreeNode01<T> findAllFatherNode(TreeNode01<T> root, TreeNode01<T> lNode, TreeNode01<T> rNode) {
            if (lNode == root || rNode == root) {
                return root;
            }
            if (root == null || lNode == null || rNode == null) {
                return null;
            }
            // 如果lNode是左子树的节点
            if (nodeIsChild(root.leftChild, lNode)) {
                if (nodeIsChild(root.rightChild, rNode)) {
                    return root;
                } else {
                    return findAllFatherNode(root.leftChild, lNode, rNode);
                }
            } else {
                if (nodeIsChild(root.leftChild, rNode)) {
                    return root;
                } else {
                    return findAllFatherNode(root.rightChild, lNode, rNode);
                }
            }
        }
    
        /**
         * 根据前序和中序构建二叉树
         *
         * @param pre
         * @param mid
         * @param <T>
         * @return
         */
        public static <T> TreeNode01<T> getTreeFromPreAndMid(List<T> pre, List<T> mid) {
            if (pre == null || mid == null || pre.size() == 0 || mid.size() == 0) {
                return null;
            }
            if (pre.size() == 1) {
                return new TreeNode01<T>(pre.get(0));
            }
            TreeNode01<T> root = new TreeNode01<T>(pre.get(0));
            // 找出根节点在中序中的位置
            int index = 0;
            while (!mid.get(index++).equals(pre.get(0))) {
    
            }
    
            // 构建左子树的前序
            List<T> preLeft = new ArrayList<T>(index);
    
            // 中子树的前序
            List<T> midLeft = new ArrayList<T>(index);
            for (int i = 1; i < index; i++) {
                preLeft.add(pre.get(i));
            }
            for (int i = 0; i < index - 1; i++) {
                midLeft.add(mid.get(i));
            }
            // 重建左子树
            root.leftChild = getTreeFromPreAndMid(preLeft, midLeft);
            // 右子树的前序
            List<T> preRight = new ArrayList<T>(pre.size() - index - 1);
            // 右子树的中序
            List<T> midRight = new ArrayList<T>(pre.size() - index - 1);
            for (int i = 0; i <= pre.size() - index - 1; i++) {
                preRight.add(pre.get(index + i));
            }
    
            for (int i = 0; i <= pre.size() - index - 1; i++) {
                midRight.add(mid.get(index + i));
            }
            // 重建→子树
            root.rightChild = getTreeFromPreAndMid(preRight, midRight);
            return root;
    
        }
    
        public static <T> boolean equals(TreeNode01<T> node1, TreeNode01<T> node2) {
            if (node1 == null && node2 == null) {
                return true;
            } else if (node1 == null || node2 == null) {
                return false;
            }
            boolean isEqual = node1.value.equals(node2.value);
            boolean isLeftEqual = equals(node1.leftChild, node2.leftChild);
            boolean isRightEqual = equals(node1.rightChild, node2.rightChild);
            return isEqual && isLeftEqual && isRightEqual;
    
        }
    
    }
  • 相关阅读:
    【Java】快速排序、归并排序、堆排序、基数排序实现总结
    【Java】二分查找、插值查找、斐波那契查找的实现,及分析
    【Java】Java实现常见的七种排序
    【C】常见的排序
    栈,迷宫问题
    海量数据处理问题
    【C】 布隆过滤器BloomFilter
    哈希变形---位图
    C实现Hash表,链式结构
    C实现Hash表,开放定址法
  • 原文地址:https://www.cnblogs.com/fmgao-technology/p/11337705.html
Copyright © 2020-2023  润新知