树——二叉树

二叉树

概述

  二叉树是一种树状结构:每个节点最多有两个孩子,左孩子和右孩子

  重要的二叉树结构

  •   完全二叉树(complete binary tree),除最后一层以外,每一层都必须填满,填充时要遵从先左后右;
  •   平衡二叉树(balance binary tree),其中每个节点的左右子树高度相差不超过 1。​​​​​​​

遍历

  1.   广度优先遍历(Breadth-first order):尽可能先访问距离根最近的节点,也称为层序遍历;
  2.   深度优先遍历(Depth-first order):对于二叉树,可以进一步分成三种(要深入到叶子节点)
    1.   pre-order 前序遍历,对于每一棵子树,先访问该节点,然后是左子树,最后是右子树
    2.   in-order 中序遍历,对于每一棵子树,先访问左子树,然后是该节点,最后是右子树
    3.   post-order 后序遍历,对于每一棵子树,先访问左子树,然后是右子树,最后是该节点

广度优先(TreeNode)

​​​​​​​

本轮开始时队列本轮访问节点
[1]1
[2, 3]2
[3, 4]3
[4, 5, 6]4
[5, 6]5
[6, 7, 8]6
[7, 8]7
[8]8
[]
  1.   初始化,将根节点加入队列;
  2.   循环处理队列中每个节点,直至队列为空;
  3.   每次循环内处理节点后,将它的孩子节点(即下一层的节点)加入队列。

深度优先(TreeNode)

​​​​​​​

递归代码
/**
 * <h3>前序遍历</h3>
 * @param node 节点
 */
static void preOrder(TreeNode node) {
    if (node == null) {
        return;
    }
    System.out.print(node.val + "\t"); // 值
    preOrder(node.left); // 左
    preOrder(node.right); // 右
}

/**
 * <h3>中序遍历</h3>
 * @param node 节点
 */
static void inOrder(TreeNode node) {
    if (node == null) {
        return;
    }
    inOrder(node.left); // 左
    System.out.print(node.val + "\t"); // 值
    inOrder(node.right); // 右
}

/**
 * <h3>后序遍历</h3>
 * @param node 节点
 */
static void postOrder(TreeNode node) {
    if (node == null) {
        return;
    }
    postOrder(node.left); // 左
    postOrder(node.right); // 右
    System.out.print(node.val + "\t"); // 值
}
非递归代码
    public void Traversal(){
        LinkedList<TreeNode> stack = new LinkedList<>();

        TreeNode curr = root; // 代表当前节点
        TreeNode pop = null; // 最近一次弹栈的元素
        while (curr != null || !stack.isEmpty()) {
            if (curr != null) {
                colorPrintln("前: " + curr.val, 31);
                stack.push(curr); // 压入栈,为了记住回来的路
                curr = curr.left;
            } else {
                TreeNode peek = stack.peek();
                // 右子树可以不处理, 对中序来说, 要在右子树处理之前打印
                if (peek.right == null) {
                    colorPrintln("中: " + peek.val, 36);
                    pop = stack.pop();
                    colorPrintln("后: " + pop.val, 34);
                }
                // 右子树处理完成, 对中序来说, 无需打印
                else if (peek.right == pop) {
                    pop = stack.pop();
                    colorPrintln("后: " + pop.val, 34);
                }
                // 右子树待处理, 对中序来说, 要在右子树处理之前打印
                else {
                    colorPrintln("中: " + peek.val, 36);
                    curr = peek.right;
                }
            }
        }
    }
    public static void colorPrintln(String origin, int color) {
        System.out.printf("\033[%dm%s\033[0m%n", color, origin);
    }

力扣题目 

  1.   144. 二叉树的前序遍历
  2.   94. 二叉树的中序遍历 
  3.   145. 二叉树的后序遍历
  4.   101. 对称二叉树
  5.   104. 二叉树的最大深度 
  6.   111. 二叉树的最小深度 
  7.   226. 翻转二叉树 
  8.   105. 从前序与中序遍历序列构造二叉树  
  9.   106. 从中序与后序遍历序列构造二叉树  

来源

  数据结构与算法

路漫漫其修远兮,吾将上下而求索。

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 什么是二叉树二叉树是一种形结构,其中每个节点最多有两个子节点。一个节点的左子节点比该节点小,右子节点比该节点大。二叉树通常用于搜索和排序。 2. 二叉树的遍历方法有哪些? 二叉树的遍历方法包括前序遍历、中序遍历和后序遍历。前序遍历是从根节点开始遍历,先访问根节点,再访问左子,最后访问右子。中序遍历是从根节点开始遍历,先访问左子,再访问根节点,最后访问右子。后序遍历是从根节点开始遍历,先访问左子,再访问右子,最后访问根节点。 3. 二叉树的查找方法有哪些? 二叉树的查找方法包括递归查找和非递归查找。递归查找是从根节点开始查找,如果当前节点的值等于要查找的值,则返回当前节点。如果要查找的值比当前节点小,则继续在左子中查找;如果要查找的值比当前节点大,则继续在右子中查找。非递归查找可以使用栈或队列实现,从根节点开始,每次将当前节点的左右子节点入栈/队列,直到找到要查找的值或者栈/队列为空。 4. 二叉树的插入与删除操作如何实现? 二叉树的插入操作是将要插入的节点与当前节点的值进行比较,如果小于当前节点的值,则继续在左子中插入;如果大于当前节点的值,则继续在右子中插入。当找到一个空节点时,就将要插入的节点作为该空节点的子节点。删除操作需要分为三种情况:删除叶子节点、删除只有一个子节点的节点和删除有两个子节点的节点。删除叶子节点很简单,只需要将其父节点的对应子节点置为空即可。删除只有一个子节点的节点,需要将其子节点替换为该节点的位置。删除有两个子节点的节点,则可以找到该节点的后继节点(即右子中最小的节点),将其替换为该节点,然后删除后继节点。 5. 什么是平衡二叉树? 平衡二叉树是一种特殊的二叉树,它保证左右子的高度差不超过1。这种平衡可以确保二叉树的查找、插入和删除操作的时间复杂度都是O(logn)。常见的平衡二叉树包括红黑和AVL

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值