【Java数据结构 -- 二叉树+树的深度优先遍历】

二叉树

  • 1. 二叉树
    • 1.1 二叉树的介绍
    • 1.2 两种特殊的二叉树
    • 1.3 二叉树的性质
    • 1.4 二叉树的存储
  • 2. 二叉树的基本操作
    • 2.1 二叉树的创建
    • 2.2 二叉树的优先遍历
    • 2.3 递归实现二叉树遍历
    • 2.4 用非递归实现二叉树遍历

1. 二叉树

1.1 二叉树的介绍

二叉树是一种数据结构,一颗二叉树是节点的集合,即每个节点最多有两个子节点,分别为左子节点和右子节点。二叉树可以为空,或者是由一个根节点 和两个指向左子树和右子树的指针

1.2 两种特殊的二叉树

  1. 满二叉树:每层的节点数都达到最大值,则该二叉树就是满二叉树 ,即如果一颗二叉树的层数为K,且节点总数是2^k - 1,则它是满二叉树
  2. 完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从0至n-1的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。

在这里插入图片描述

1.3 二叉树的性质

  1. 若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有2^i -1(i>0)个结点
  2. 若规定只有根结点的二叉树的深度为1,则深度为k的二叉树的最大结点数是2^k -1(k>=0)
  3. 对任何一颗二叉树,如果叶结点个数为n0,度为2的非叶子结点个数为n2,则有n0 = n2+1
  4. 具有n个结点的完全二叉树如果按照从上至下,从左至右的顺序对所有结点从0开始编号,则对于序号为i的结点有
  • ** 若i>0,双亲序号:(i-2)/2;i = 0,i为根结点编号**,无双亲结点
  • 若2i+1<n,左孩子序号:2i+1,否则无左孩子
  • 若2i+2<n,右孩子序号:2i+2,否则无右孩子

1.4 二叉树的存储

二叉树的存储结构分为:顺序存储(即堆)类似于链表的链式存储
二叉树的链式存储是通过一个一个的节点引用起来的,常见的表示方式有二叉和三叉表示方式(一般用孩子表示法):

// 孩子表示法
class Node {
	int val; // 数据域
	Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树
	Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树
}
// 孩子双亲表示法
class Node {
	int val; // 数据域
	Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树
	Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树
	Node parent; // 当前节点的根节点
}

2. 二叉树的基本操作

2.1 二叉树的创建

创建一个如下的二叉树
在这里插入图片描述

public class BinaryTree {
    static class TreeNode {
        public char val;
        public TreeNode left;
        public TreeNode right;


        public TreeNode(char val) {
            this.val = val;
        }
    }

    //public TreeNode root;
    //创建二叉树  创建成功后  返回根节点
    public TreeNode createTree() {
        TreeNode A = new TreeNode('A');
        TreeNode B = new TreeNode('B');
        TreeNode C = new TreeNode('C');
        TreeNode D = new TreeNode('D');
        TreeNode E = new TreeNode('E');
        TreeNode F = new TreeNode('F');
        TreeNode G = new TreeNode('G');
        TreeNode H = new TreeNode('H');

        A.left = B;
        A.right = C;
        B.left = D;
        B.right = E;
        C.left = F;
        C.right = G;
        E.right = H;

        return A;
    }
}

2.2 二叉树的优先遍历

二叉树的优先遍历是指按照一定顺序访问二叉树中的所有节点。常见的三种优先遍历方式包括:前序遍历、中序遍历和后序遍历。可以使用递归实现、非递归实现这三种遍历方式。

  • NLR:前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点—>根的左子树—>根的右子树,即根-左-右
  • LNR:中序遍历(Inorder Traversal)——根的左子树—>根节点—>根的右子树,即左-根-右
  • LRN:后序遍历(Postorder Traversal)——根的左子树—>根的右子树—>根节点,即左-右-根

2.3 递归实现二叉树遍历

在这里插入图片描述

  • 前序遍历:上图该二叉树的前序遍历为:A B D E H C F G
    思路:在递归之前先打印当前根结点的值,然后向左子树递出,每一次都需要对当前结点的值访问,直到node为null时,左子树结束递出。当右子树此时也为node==null,从叶子结点开始回归,回归到上一个结点的右子树。
void preOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        System.out.print(root.val+"");
        preOrder(root.left);
        preOrder(root.right);
    }
  • 中序遍历:D B E H A F C G
    思路:向左子树递出,一直下去,直到node 为null 时,左子树结束递出。再来对当前节点的值进行访问,接着继续向着右子树递出,当右子树此时也为 node == null 时,从叶子节点开始回归,回归到上一个节点的右子树前先对当前节点的值进行访问。
// 中序 : 左 根 右
    void inOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        inOrder(root.left);
        System.out.print(root.val+"");
        inOrder(root.right);
    }
  • 后序遍历:D H E B F G C A
    向左子树递出,一直下去,直到 node 为 null 时,左子树结束递出。再接着继续向着右子树递出,再来对当前节点的值进行访问,当右子树此时也为 node 为 null 时,从叶子节点开始回归,回归到对当前节点的值进行访问
// 后序 : 左 右  根
    void postOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        postOrder(root.left);
        postOrder(root.right);
        System.out.print(root.val+"");
    }

2.4 用非递归实现二叉树遍历

  • 非递归前序遍历:
    思路:
void preOrderNor(TreeNode root) {
        if (root == null) {
            return;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;

        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                System.out.print(cur.val+" ");
                cur = cur.left;
            }
            TreeNode top = stack.pop();
            cur = top.right;
        }
    }
  • 非递归中序遍历:
void inOrderNor(TreeNode root) {
        if (root == null) {
            return;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;

        while (cur != null || !stack.isEmpty()) {
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            TreeNode top = stack.pop();
            System.out.print(top.val + " ");
            cur = top.right;
        }

    }
  • 非递归后序遍历:
void postOrderNor(TreeNode root) {
        if (root == null) {
            return;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        TreeNode prev = null;

        while (cur != null || !stack.isEmpty()) {
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }

            TreeNode top = stack.peek();
            if (top.right == null || top.right == prev) {
                System.out.print(top.val + " ");
                stack.pop();
                prev = top;     //记录下最新被打印的那个节点
            }else {
                cur = top.right;
            }
        }

    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/422956.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

虚拟机数据恢复-虚拟机误还原快照后如何恢复还原前的数据?

虚拟机数据恢复环境&故障&#xff1a; 由一台物理服务器迁移到ESXI上的虚拟机&#xff0c;虚拟机迁移完成后做了一个快照&#xff0c;该ESXI上面一共运行了数十台虚拟机。某天工作人员不小心将快照进行了还原&#xff0c;虚拟机内的数据还原到了数年前刚迁移过来时的状态&a…

超详细的 pytest 钩子函数 之初始钩子和引导钩子来啦

前几篇文章介绍了 pytest 点的基本使用&#xff0c;学完前面几篇的内容基本上就可以满足工作中编写用例和进行自动化测试的需求。从这篇文章开始会陆续给大家介绍 pytest 中的钩子函数&#xff0c;插件开发等等。 仔细去看过 pytest 文档的小伙伴&#xff0c;应该都有发现 pyt…

利用小蜜蜂AI智能问答ChatGPT+AI高清绘图生成图文故事案例

利用小蜜蜂AI智能问答ChatGPTAI高清绘图生成图文故事案例 这段时间利用小蜜蜂AI网站做了一些编程、绘图以及数据分析方面的案例。再过几个月&#xff0c;我的大孙子就要出生了。我要用小蜜蜂AI智能问答和AI高清绘图为大孙子生成一个1-9的数字图文故事。 小蜜蜂AI网站可以扫如…

DangZero:通过直接页表访问的高效UAF检测(DangZero实现IMPLEMENTATION翻译)

We implement DangZero as a shared library that overlays the de- fault memory allocator via LD_PRELOAD. Additionally, DangZero requires a backend to be available for direct page table access, which we describe in detail in the following section. 我们将DangZ…

CTFHUB 命令执行

命令执行 原理&#xff1a; 在编写程序的时候&#xff0c;当碰到要执行系统命令来获取一些信息时&#xff0c;就要调用外部命令的函数&#xff0c;比如php中的exec()、system()等&#xff0c;如果这些函数的参数是由用户所提供的&#xff0c;那么恶意用户就可能通过构造命令拼…

Android编程环境搭建

一、下载软件&#xff1a; JDK、Android SDK、Android Studio 1.1 首先下载安装JDK 登录Java Downloads | Oracle网站下载javaJDK11&#xff0c;具体步骤如图1所示 图1 下载安装JDK 1.2 下载安装 Android Studio 到 Android Studio 的官网上下载对应安装包&#xff0c;链接…

20240301-2-ZooKeeper面试题(二)

11. Chroot 特性 3.2.0 版本后&#xff0c;添加了 Chroot 特性&#xff0c;该特性允许每个客户端为自己设置一个命名空间。如果一个客户端设置了 Chroot&#xff0c;那么该客户端对服务器的任何操作&#xff0c;都将会被限制在其自己的命名空间下。 通过设置 Chroot&#xff…

腾讯云-云+校园扶持-2核2G学生服务器套餐30元起

2024年腾讯云学生服务器优惠活动「云校园」&#xff0c;学生服务器优惠价格&#xff1a;轻量应用服务器2核2G学生价30元3个月、58元6个月、112元一年&#xff0c;轻量应用服务器4核8G配置191.1元3个月、352.8元6个月、646.8元一年&#xff0c;CVM云服务器2核4G配置842.4元一年&…

【树莓派系统配置+python3.8+环境配置踩坑点汇总】raspberrypi

最近又开始搞树莓派的深度学习模型。很多windows端的环境需要在树莓派上重新部署&#xff0c;中间出现了非常多的问题。主要以各种库的下载安装为主要。 首先&#xff0c;第一个问题&#xff1a; 树莓派系统烧录之后&#xff0c;默认apt一般需要升级看&#xff0c;而默认下载…

YOLOv9:Learning What You Want to Learn Using Programmable Gradient Information

YOLOv9&#xff1a;Learning What You Want to Learn Using Programmable Gradient Information 摘要 今天的深度学习方法关注的是如何设计最合适的目标函数&#xff0c;使模型的预测结果最接近ground truth的真实情况。同时&#xff0c;必须设计一个适当的体系结构&#xff…

【Vue3】函数式编程(h 函数)

h 函数的原理就是 createVNode。可以使用 h 函数封装一些小组件。 <template><table border><tr><th>name</th><th>age</th><th>操作</th></tr><tr v-for"item in list" :key"item.age"&…

基于 LLaMA 和 LangChain 实践本地 AI 知识库

有时候,我难免不由地感慨,真实的人类世界,本就是一个巨大的娱乐圈,即使是在英雄辈出的 IT 行业。数日前,Google 正式对外发布了 Gemini 1.5 Pro,一个建立在 Transformer 和 MoE 架构上的多模态模型。可惜,这个被 Google 寄予厚望的产品并未激起多少水花,因为就在同一天…

免费的ChatGPT网站( 7个 )

ChatGPT 是由 OpenAI 公司研发的一款大型语言模型&#xff0c;它可以实现智能聊天、文本生成、语言翻译等多种功能。以下是 ChatGPT 的详细介绍&#xff1a; 智能聊天&#xff1a;ChatGPT 可以与用户进行自然语言对话&#xff0c;回答用户的问题&#xff0c;提供相关的信息和建…

(Linux学习三)用户管理相关文件详解,用户以及用户组的基本操作命令

一. 用户管理相关文件介绍 /etc/passwd 文件里面存 储了用户信息&#xff0c;一共7列数据 冒号分割列 /etc/shadow 用户密码加密信息&#xff0c;9列数据 /etc/group 用户组信息&#xff0c;4列数据 1. /etc/passwd文件7列数据详解&#xff1a; root:x:0:0:root:/root:/bin/…

[伴学笔记]01-操作系统概述 [南京大学2024操作系统]

文章目录 前言jyy:01-操作系统概述 [南京大学2024操作系统]为什么要学操作系统?学习操作系统能得到什么? 什么是操作系统?想要明白什么是操作系统:时间线:1940s1950s-1960s1960-1970s年代. 信息来源: 前言 督促自己,同时分享所得,阅读完本篇大约需要10分钟,希望为朋友的技术…

Tomcat -2

1. 动静分离 ① 单机反向代理 7-2 代理服务器 7-5 tomcat 设置 7-3 测试&#xff1a; 代理服务器那里写什么就显示什么

git代码上库流程(一篇就够了)

文章目录 一、前言二、创建新分支三、修改代码四、合并分支 一、前言 多人协同开发一个项目&#xff0c;为了方便管理代码&#xff0c;每个人代码提交不冲突。git代码仓库管理是不可或缺的。对于新手来说&#xff0c;既不懂git原理又不懂底层逻辑&#xff0c;还经常错误提交代码…

腾讯云学生服务器使用教程_申请腾讯云学生机详细流程

2024年腾讯云学生服务器优惠活动「云校园」&#xff0c;学生服务器优惠价格&#xff1a;轻量应用服务器2核2G学生价30元3个月、58元6个月、112元一年&#xff0c;轻量应用服务器4核8G配置191.1元3个月、352.8元6个月、646.8元一年&#xff0c;CVM云服务器2核4G配置842.4元一年&…

哪个超声波清洗机品牌值得入手?销量榜品牌值得选购!

在科技日益发展的今天&#xff0c;超声波清洗技术以其高效、便捷和深度清洁的特点&#xff0c;已经深入到生活的诸多领域&#xff0c;从精密仪器到珠宝首饰&#xff0c;从眼镜框到假牙&#xff0c;甚至是厨房用品的日常护理&#xff0c;都能见到超声波清洗机的身影。面对市场上…

DataSpell 2023:专注于数据,加速您的数据科学之旅 mac/win版

JetBrains DataSpell 2023是一款专为数据科学家和数据分析师设计的集成开发环境&#xff08;IDE&#xff09;。这款IDE提供了强大的数据分析和可视化工具&#xff0c;旨在帮助用户更快速、更高效地进行数据科学工作。 DataSpell 2023软件获取 DataSpell 2023在保持其一贯的数…