算法练习 Day14 | LeetCode 144,145,94

本文介绍了二叉树的四种主要分类(满二叉树、完全二叉树、二叉搜索树和平衡二叉搜索树),以及两种常见的存储方式(顺序存储和链式存储)。同时详细讲解了深度优先遍历(包括前序、中序和后序)的递归和迭代实现方法,以及在LeetCode中的应用实例。
摘要由CSDN通过智能技术生成

先导知识:

一、二叉树的分类

(1)满二叉树:除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树


(2)完全二叉树:一颗深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这颗二叉树称为完全二叉树。


(3)二叉搜索树:若它的左子树不空,则左子树上的所有结点的值均小于它的根节点的值;若它的右子树不空,则右子树上所有结点的值均大于他的根节点的值

(4)平衡二叉搜索树:平衡二叉搜索树具有以下性质:它是一颗空树或者它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树

二、二叉树的存储方式

(1)顺序存储

顺序存储就是用数组,顺序存储的元素在内存中是连续分布的

如果父节点的数组下标是i,那么它的左孩子就是i*2+1,右孩子就是i*2+2
(2)链式存储

链式存储就是用指针,链式存储是通过指针把分布在各个地址的节点串联在一起

三、二叉树的遍历方式

(1)深度优先遍历:先往深走,遇到叶子节点再往回走

前序遍历:中左右(需要掌握递归法、迭代法)

中序遍历:左中右(需要掌握递归法、迭代法)

后序遍历:左右中(需要掌握递归法、迭代法)

前序:5412678

中序:1425768

后序:1247865

(2)广度优先遍历:一层一层的去遍历

层次遍历(迭代法)

LeetCode 144:二叉树的前序遍历

题目描述:

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

解法一:递归

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        preorder(root, result);
        return result;
    }

    private void preorder(TreeNode root, List<Integer> result) {
        if (root == null) {
            return;
        }
        //前序遍历 中左右
        result.add(root.val);
        preorder(root.left, result);
        preorder(root.right, result);
    }

解法二:迭代

    /**
     * 迭代方式 
     * @param root
     * @return
     */
    public List<Integer> preorderTraversal1(TreeNode root) {
        //前序遍历 : 中左右
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result.add(node.val);
            //栈为先进后出,所以先将右节点压入栈,在将左节点压入栈
            if (node.right != null) {
                stack.push(node.right);
            }
            if (node.left != null) {
                stack.push(node.left);
            }
        }
        return result;
    }

LeetCode 145:二叉树的后序遍历

题目描述:

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 

解法一:递归

    public static List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        postorder(root, result);
        return result;
    }

    private static void postorder(TreeNode root, List<Integer> result) {
        if (root == null) {
            return;
        }
        //后序遍历    左右中
        postorder(root.left, result);
        postorder(root.right, result);
        result.add(root.val);
    }

解法二:迭代

    public static List<Integer> postorderTraversal1(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        //后序遍历:左右中 进栈的顺序为中左右 -> 出栈的顺序是中右左, 
           将数组进行反转,这样就变成了左右中
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result.add(node.val);
            if (node.left != null) {
                stack.push(node.left);
            }
            if (node.right != null) {
                stack.push(node.right);
            }
        }
        Collections.reverse(result);
        return result;
    }

LeetCode 94:二叉树的中序遍历

题目描述:

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

解法一:递归

   public static List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        inorder(root, result);
        return result;
    }

    private static void inorder(TreeNode root, List<Integer> result) {
        if (root == null) {
            return;
        }
        //中序遍历 左中右
        inorder(root.left, result);
        result.add(root.val);
        inorder(root.right, result);
    }

解法二:迭代

 public static List<Integer> inorderTraversal1(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while (cur != null || !stack.isEmpty()) {
            //一路向左进行遍历,将所有左边的数据压入栈中
            if (cur != null) {
                stack.push(cur);
                cur = cur.left;
            } else {
                //如果当前的节点为空,则将栈顶的数据弹出,将该节点加入result中,继续遍历右节点
                cur = stack.pop();
                result.add(cur.val);
                cur = cur.right;
            }
        }
        return result;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值