二叉树数据结构

二叉树数据结构

  由于在LeetCode上刷题时遇到二叉树的问题都会非常头疼,因为二叉树的数据结构在本机没有实现。因此此类编程题目无法在本机进行运行,更无法改错啦!为了解决这个麻烦,于是自己简单实现了一个二叉树的数据结构,构造参数通过Object数组进行初始化。toString()中集成了层序遍历、前序遍历、中序遍历和后序遍历。

前序遍历

采用递归法进行前序遍历

    private List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        preorder(root,list);
        return list;
    }
    private void preorder(TreeNode root,List<Integer> list) {
        if(root != null){
            list.add(root.val);
            preorder(root.left,list);
            preorder(root.right,list);
        }
    }

中序遍历

采用迭代法+栈进行中序遍历

    private List<Integer> inorderTraversal(TreeNode root) {
        List<Integer>list = new ArrayList<>();
        if(root==null)return list;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while (!stack.isEmpty()|| cur != null){
            if(cur != null){
                stack.push(cur);
                cur = cur.left;
            }else{
                cur = stack.pop();
                list.add(cur.val);
                cur = cur.right;
            }
        }
        return list;
    }

后序遍历

采用迭代法+自定义数据结构Command进行后续遍历

    private List<Integer> postorderTraversal(TreeNode root) {
        List<Integer>list = new ArrayList<>();
        if(root==null)return list;
        Stack<Command> stack = new Stack<>();
        stack.push(new Command("go",root));
        while (!stack.isEmpty()){
            Command cur = stack.pop();
            if(cur.message.equals("print")){
                list.add(cur.node.val);
            }else{
                stack.push(new Command("print",cur.node));
                if(cur.node.right!=null)stack.push(new Command("go",cur.node.right));
                if(cur.node.left!=null)stack.push(new Command("go",cur.node.left));
            }

        }
        return list;
    }
    /**
     * @Author CourageHe
     * @Description  后续遍历的辅助数据结构,可通过Pair代替
     * @Date 2020/6/9 0:33
     **/
    private class Command {
        String message;
        TreeNode node;
        Command(String message, TreeNode node) { this.message = message;this.node = node;}
    }

层序遍历

采用迭代法+队列 进行层序遍历

    private List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> list = new ArrayList<>();

        Queue<Pair<TreeNode,Integer>> queue = new ArrayDeque<>();
        queue.add(new Pair<>(root,0));

        while (!queue.isEmpty()){
            TreeNode node = queue.peek().getKey();
            int level = queue.peek().getValue();
            queue.poll();
            //如果节点为空,则跳过
            if(node == null) continue;
            //如果该层没有列表 则新建
            if(level == list.size())
                list.add(new ArrayList<>());

            list.get(level).add(node.val);
            queue.add(new Pair<>(node.left,level+1));
            queue.add(new Pair<>(node.right,level+1));
        }
        return list;
    }

完整代码

import javafx.util.Pair;

import java.util.*;

public class TreeNode {

    public int val;
    public TreeNode left;
    public TreeNode right;

    private Queue<TreeNode> queue = new ArrayDeque<>();


    public TreeNode(int x) {
        val = x;
    }

    //根据n个元素的数组arr创建一个链表
    //使用arr为参数,创建另外一个listnode的构造函数
    public TreeNode(Object[] arr) {
        this.val = (int)arr[0];
        TreeNode cur = this;
        for (int i = 1; i < arr.length; i+=2) {
            if(arr[i] != null ){
                cur.left = new TreeNode((int)arr[i]);
                queue.add(cur.left);
            }
            if(arr[i+1] != null ){
                cur.right = new TreeNode((int)arr[i+1]);
                queue.add(cur.right);
            }
            cur = queue.poll();
        }
    }

    @Override
    public String toString() {
        StringBuilder s = new StringBuilder();
        s.append("层序遍历:"+levelOrder(this)+"\n");
        s.append("前序遍历:"+preorderTraversal(this)+"\n");
        s.append("中序遍历:"+inorderTraversal(this)+"\n");
        s.append("后序遍历:"+postorderTraversal(this)+"\n");

        return s.toString();
    }
    /**
     * @Author CourageHe
     * @Description 树的层序遍历
     * @Date 2020/6/9 0:09
     * @Param [root]
     * @return java.util.List<java.util.List<java.lang.Integer>>
     **/
    private List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> list = new ArrayList<>();

        Queue<Pair<TreeNode,Integer>> queue = new ArrayDeque<>();
        queue.add(new Pair<>(root,0));

        while (!queue.isEmpty()){
            TreeNode node = queue.peek().getKey();
            int level = queue.peek().getValue();
            queue.poll();
            //如果节点为空,则跳过
            if(node == null) continue;
            //如果该层没有列表 则新建
            if(level == list.size())
                list.add(new ArrayList<>());

            list.get(level).add(node.val);
            queue.add(new Pair<>(node.left,level+1));
            queue.add(new Pair<>(node.right,level+1));
        }
        return list;
    }


    /**
     * @Author CourageHe
     * @Description 树的前序遍历
     * @Date 2020/6/9 0:14
     * @Param [root]
     * @return java.util.List<java.lang.Integer>
     **/
    private List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        preorder(root,list);
        return list;
    }
    private void preorder(TreeNode root,List<Integer> list) {
        if(root != null){
            list.add(root.val);
            preorder(root.left,list);
            preorder(root.right,list);
        }
    }

    /**
     * @Author CourageHe
     * @Description  中序遍历
     * @Date 2020/6/9 0:29
     * @Param [root]
     * @return java.util.List<java.lang.Integer>
     **/
    private List<Integer> inorderTraversal(TreeNode root) {
        List<Integer>list = new ArrayList<>();
        if(root==null)return list;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while (!stack.isEmpty()|| cur != null){
            if(cur != null){
                stack.push(cur);
                cur = cur.left;
            }else{
                cur = stack.pop();
                list.add(cur.val);
                cur = cur.right;
            }
        }
        return list;
    }


    /**
     * @Author CourageHe
     * @Description 树的后序遍历
     * @Date 2020/6/9 0:31
     * @Param [root]
     * @return java.util.List<java.lang.Integer>
     **/
    private List<Integer> postorderTraversal(TreeNode root) {
        List<Integer>list = new ArrayList<>();
        if(root==null)return list;
        Stack<Command> stack = new Stack<>();
        stack.push(new Command("go",root));
        while (!stack.isEmpty()){
            Command cur = stack.pop();
            if(cur.message.equals("print")){
                list.add(cur.node.val);
            }else{
                stack.push(new Command("print",cur.node));
                if(cur.node.right!=null)stack.push(new Command("go",cur.node.right));
                if(cur.node.left!=null)stack.push(new Command("go",cur.node.left));
            }

        }
        return list;
    }
    /**
     * @Author CourageHe
     * @Description  后续遍历的辅助数据结构,可通过Pair代替
     * @Date 2020/6/9 0:33
     **/
    private class Command {
        String message;
        TreeNode node;
        Command(String message, TreeNode node) { 
            this.message = message;this.node = node;
        }
    }

    public static void main(String[] args) {
        Object []arr = {3,9,20,null,null,15,7};
        TreeNode root = new TreeNode(arr);
        System.out.println(root);
    }


}
全部评论

相关推荐

03-13 00:04
已编辑
吉林大学 Java
约面的挺突然。。狠下心接了1.自我介绍2.讲讲JAVA的反射3.可以继续讲讲AOP,动态代理[&nbsp;因为讲反射不小心吟唱到了例如AOP的动态代理,但是这块记忆的非常不熟,结果磕磕绊绊&nbsp;]4.项目我看你写了AOP和注解,具体怎么实现滑动窗口限流的[&nbsp;梦到什么说什么,吟唱八股发散千万不要散到自己不熟悉的区域&nbsp;]5.也讲讲为什么另一个项目选择令牌桶,具体流程6.&nbsp;OK,讲讲&nbsp;Redis&nbsp;的数据类型?还有吗?就了解这五种嘛[&nbsp;把5个的基础类型从应用对比到历届底层全都吟唱了一遍。一句还有吗直接没力气了,简历就写了理解5种,别的我是真一点没看TT&nbsp;]7.讲讲Redission分布式锁实现8.这个指数退避怎么实现的9.在这里有考虑去保障幂等性嘛10.这里为什么使用指数退避呢?&nbsp;什么时候用均匀重传[已经晕过去了说不了解,刚说了后就意识到,估计应该说指数退避能缓解压力防止下游服务器雪崩之类的]11.ok,那讲讲JMM12.讲讲RocketMQ如何保证的不丢消息13.讲讲RocketMQ延迟消息原理14.讲讲项目Redis实现会话记忆这一块15.如果ai调用function&nbsp;calling出现幻觉,有考虑怎么解决吗?[&nbsp;不了解,面试官说什么接口幂等化,高危操作人工防护,没在听,感觉人已经飞升了TT&nbsp;]16.mcp了解嘛?和function&nbsp;calling有什么区别[&nbsp;依旧不了解,只能说了个前者规范架构抽象解耦,后者耦合高只能算个工具调用]17.AI生成代码的代码质量怎么保障,那平时如何review的呢18.算法。lc215&nbsp;&nbsp;数组中最大第k个元素19.打算考研还是本科就业20.反问1️⃣有哪里不足,有哪些需要提高的部分。[主要说知识广度不够,多刷算法,让我别太紧张]2️⃣部门业务会做什么人生第二次面试。感觉大厂面试官的气场压力很大应该凉了不过这次面试非常锻炼心态,多面试,多面试。
冰炸橙汁_不做oj版:redis除了五种基本数据类型,其他的几种还是要掌握一下的,挺常用
点赞 评论 收藏
分享
Edgestr:没项目地址就干脆把那一栏删了呗
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务