数据结构第09节:二叉树

树是一种非线性的数据结构,它由节点和边组成。每个节点可以有零个或多个子节点。在树中,没有循环,并且所有的节点都是通过边连接的。

  1. 树的基本概念:

    • 根节点:没有父节点的唯一节点。
    • 子节点:一个节点可以直接拥有零个或多个子节点。
    • 父节点:每个子节点都有一个父节点,除了根节点。
    • 叶子节点:没有任何子节点的节点。
    • 兄弟节点:具有相同父节点的节点。
    • 路径:从一个节点到另一个节点的一系列连续的边。
    • 深度:从根节点到特定节点的路径长度。
    • 高度:树中任何节点的最大深度。
  2. Java中的树实现:

下面是一个简单的二叉树的例子:

public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) {val = x;}
}public class BinaryTree {TreeNode root;public BinaryTree() {root = null;}public void add(int value) {root = addRecursive(root, value);}private TreeNode addRecursive(TreeNode current, int value) {if (current == null) {return new TreeNode(value);}if (value < current.val) {current.left = addRecursive(current.left, value);} else if (value > current.val) {current.right = addRecursive(current.right, value);}return current;}
}

在这个例子中,我们创建了一个二叉树,其中每个节点最多有两个子节点:左子节点和右子节点。我们还实现了一个添加新节点的方法,该方法会根据新值与当前节点值的大小关系,将新节点添加到左子树或右子树。

  1. 使用案例:

假设我们要创建一个学生信息的二叉搜索树,我们可以使用上面定义的二叉树类,但是我们需要修改节点类以存储学生的姓名和年龄,如下所示:

public class StudentNode {String name;int age;StudentNode left;StudentNode right;StudentNode(String name, int age) {this.name = name;this.age = age;}
}

然后,我们可以创建一个新的二叉树,并添加学生信息:

public class StudentTree {StudentNode root;public StudentTree() {root = null;}public void addStudent(String name, int age) {root = addStudentRecursive(root, name, age);}private StudentNode addStudentRecursive(StudentNode current, String name, int age) {if (current == null) {return new StudentNode(name, age);}if (age < current.age) {current.left = addStudentRecursive(current.left, name, age);} else if (age > current.age) {current.right = addStudentRecursive(current.right, name, age);}return current;}
}

在这个例子中,我们创建了一个新的二叉树,用于存储学生的信息。我们使用学生的年龄作为比较标准,将学生信息添加到树中。

让我们继续扩展上述的学生信息二叉搜索树的案例,这次我们将添加查找学生信息的功能。

首先,我们需要在StudentNode类中添加一个toString()方法,以便我们可以打印出学生的信息:

public class StudentNode {String name;int age;StudentNode left;StudentNode right;StudentNode(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "StudentNode{" +"name='" + name + '\'' +", age=" + age +'}';}
}

然后,在StudentTree类中,我们可以添加一个查找学生信息的方法:

public class StudentTree {// ...public StudentNode findStudent(int age) {return findStudentRecursive(root, age);}private StudentNode findStudentRecursive(StudentNode current, int age) {if (current == null) {return null;}if (age == current.age) {return current;}if (age < current.age) {return findStudentRecursive(current.left, age);} else {return findStudentRecursive(current.right, age);}}
}

这个findStudent()方法会返回指定年龄的学生信息,如果找不到,则返回null

现在,我们可以创建一个main()方法来测试我们的二叉搜索树:

public class Main {public static void main(String[] args) {StudentTree tree = new StudentTree();tree.addStudent("Alice", 20);tree.addStudent("Bob", 22);tree.addStudent("Charlie", 18);System.out.println(tree.findStudent(20)); // 输出: StudentNode{name='Alice', age=20}System.out.println(tree.findStudent(22)); // 输出: StudentNode{name='Bob', age=22}System.out.println(tree.findStudent(18)); // 输出: StudentNode{name='Charlie', age=18}System.out.println(tree.findStudent(25)); // 输出: null}
}

在这个例子中,我们首先创建了一个学生信息的二叉搜索树,并添加了三个学生的信息。然后,我们使用findStudent()方法查找并打印出学生的信息。

接下来,我们可以在StudentTree类中添加删除学生信息的功能。

首先,我们创建一个删除学生信息的方法,这可能比添加和查找更复杂,因为我们需要处理三种情况:删除的节点是叶子节点、删除的节点有一个子节点、删除的节点有两个子节点。

public class StudentTree {// ...public void deleteStudent(int age) {root = deleteStudentRecursive(root, age);}private StudentNode deleteStudentRecursive(StudentNode current, int age) {if (current == null) {return null;}if (age == current.age) {if (current.left == null && current.right == null) {return null;}if (current.right == null) {return current.left;}if (current.left == null) {return current.right;}int smallestValue = findMin(current.right);current.age = smallestValue;current.right = deleteStudentRecursive(current.right, smallestValue);return current;}if (age < current.age) {current.left = deleteStudentRecursive(current.left, age);return current;}current.right = deleteStudentRecursive(current.right, age);return current;}private int findMin(StudentNode node) {return node.left == null ? node.age : findMin(node.left);}
}

在这个例子中,deleteStudent()方法会删除指定年龄的学生信息。如果要删除的节点是叶子节点或者只有一个子节点,那么我们直接删除该节点即可。如果要删除的节点有两个子节点,我们找到其右子树中的最小节点(即下一个最大的节点),用它替换要删除的节点,然后删除这个最小节点。

最后,我们可以在Main类中测试一下删除功能:

public class Main {public static void main(String[] args) {StudentTree tree = new StudentTree();tree.addStudent("Alice", 20);tree.addStudent("Bob", 22);tree.addStudent("Charlie", 18);System.out.println(tree.findStudent(20)); // 输出: StudentNode{name='Alice', age=20}tree.deleteStudent(20);System.out.println(tree.findStudent(20)); // 输出: nullSystem.out.println(tree.findStudent(22)); // 输出: StudentNode{name='Bob', age=22}tree.deleteStudent(22);System.out.println(tree.findStudent(22)); // 输出: nullSystem.out.println(tree.findStudent(18)); // 输出: StudentNode{name='Charlie', age=18}tree.deleteStudent(18);System.out.println(tree.findStudent(18)); // 输出: null}
}

在这个例子中,我们首先创建了一个学生信息的二叉搜索树,并添加了三个学生的信息。然后,我们使用deleteStudent()方法删除学生信息,再使用findStudent()方法验证是否删除成功。

在上一节中,我们已经实现了二叉搜索树的添加、查找和删除操作。接下来,我们将实现遍历操作。二叉树的遍历主要有三种方式:前序遍历、中序遍历和后序遍历。

前序遍历的顺序是:先访问根节点,然后递归地进行左子树的前序遍历,最后递归地进行右子树的前序遍历。

中序遍历的顺序是:先递归地进行左子树的中序遍历,然后访问根节点,最后递归地进行右子树的中序遍历。

后序遍历的顺序是:先递归地进行左子树的后序遍历,然后递归地进行右子树的后序遍历,最后访问根节点。

我们将在StudentTree类中添加这些遍历方法:

public class StudentTree {// ...public void preOrderTraversal() {preOrderTraversalRecursive(root);}private void preOrderTraversalRecursive(StudentNode node) {if (node != null) {System.out.print(node + " ");preOrderTraversalRecursive(node.left);preOrderTraversalRecursive(node.right);}}public void inOrderTraversal() {inOrderTraversalRecursive(root);}private void inOrderTraversalRecursive(StudentNode node) {if (node != null) {inOrderTraversalRecursive(node.left);System.out.print(node + " ");inOrderTraversalRecursive(node.right);}}public void postOrderTraversal() {postOrderTraversalRecursive(root);}private void postOrderTraversalRecursive(StudentNode node) {if (node != null) {postOrderTraversalRecursive(node.left);postOrderTraversalRecursive(node.right);System.out.print(node + " ");}}
}

然后,我们可以在Main类中测试一下遍历功能:

public class Main {public static void main(String[] args) {StudentTree tree = new StudentTree();tree.addStudent("Alice", 20);tree.addStudent("Bob", 22);tree.addStudent("Charlie", 18);System.out.println("Pre-order traversal:");tree.preOrderTraversal(); // 输出: StudentNode{name='Charlie', age=18} StudentNode{name='Alice', age=20} StudentNode{name='Bob', age=22}System.out.println("\nIn-order traversal:");tree.inOrderTraversal(); // 输出: StudentNode{name='Charlie', age=18} StudentNode{name='Alice', age=20} StudentNode{name='Bob', age=22}System.out.println("\nPost-order traversal:");tree.postOrderTraversal(); // 输出: StudentNode{name='Charlie', age=18} StudentNode{name='Bob', age=22} StudentNode{name='Alice', age=20}}
}

在这个例子中,我们首先创建了一个学生信息的二叉搜索树,并添加了三个学生的信息。然后,我们分别进行了前序遍历、中序遍历和后序遍历,并打印出了遍历结果。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM的五大内存区域

JVM的五大内存区域 JVM内存区域最粗略的划分可以分为 堆 和 栈 &#xff0c;当然&#xff0c;按照虚拟机规范&#xff0c;可以划分为以下几个区域&#xff1a; JVM内存分为线程独享区和线程共享区&#xff0c; 其中 方法区 和 堆 是线程共享区&#xff0c; 虚拟机栈, 本地方法…

[知识点]-[宽搜bfs]

离开中山路 #include<bits/stdc.h> #define fi first #define se second #define pb push_back #define PII pair<int,int > #define int long long #define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);using namespace std;const int N 1e6…

延边幼儿园1*3 OLED柔性屏翻页一体机安装项目

一、产品介绍 本次项目在吉林省延吉市延边幼儿园内&#xff0c;引入了先进的55寸1*3 OLED柔性屏翻页一体机。该设备集高清显示、灵活翻页、互动教学等功能于一体&#xff0c;专为现代幼儿教育环境设计&#xff0c;旨在通过科技手段提升教学质量&#xff0c;丰富教学手段&#x…

数据库重命名脚本

由于原本的数据库命名不规范&#xff0c;需要进行重新命名&#xff0c;最终确定方案为新建数据库后迁移表&#xff0c;以下为脚本。 #!/bin/bashecho -e "\033[34m 此脚本功能为修改数据库名称&#xff08;需要新建数据库后将数据迁移到新数据库&#xff09;&#xff0c;…

rtsp client c++

直接上代码&#xff1a;源码 void doRtspParse(char *b) {std::vector<std::string> res;char *ptr b, *ptr1 nullptr;while ((ptr1 strstr(ptr, "\r\n"))) {res.push_back(std::string(ptr, ptr1 - ptr));ptr ptr1 2;}int len ptr - b;b[len - 1] \0;…

1.1.2数据结构的三要素

一.数据结构的三要素 数据结构这门课着重关注的是数据元素之间的关系&#xff0c;和对这些数据元素的操作&#xff0c;而不关心具体的数据项内容 。 1.逻辑结构 &#xff08;1&#xff09;集合结构 &#xff08;2&#xff09;线性结构 数据元素之间是一对一的关系。除了第一个…

如何选择鼠标和键盘@无线外设鼠标键盘连接方案对比

文章目录 鼠标续航问题充电接口鼠标模式数低功耗蓝牙总结 键盘首要因素&#x1f47a;下面是详细对比 鼠标 关于蓝牙鼠标、2.4GHz无线鼠标和有线鼠标的详细对比表格&#xff0c;特别关注消费者相关的特性&#xff1a; 特性蓝牙鼠标2.4GHz无线鼠标有线鼠标连接方式蓝牙2.4GHz无…

MongoDB-社区版-本地安装

系统&#xff1a;win10 1. 下载server:Download MongoDB Community Server | MongoDB 我选的zip包 2. 下载shell&#xff1a;MongoDB Shell Download | MongoDB 我选的zip包 3. 启动server 4. 启动shell, 完成

这样拼板帮你省近万元,堪称PCB工程师成本终结者!

别再被骗了&#xff0c;打PCB板价格高不是单价高&#xff01;而是你的拼板导致利用率太低了&#xff01; 今天给大家讲个小故事&#xff0c;教大家如何省钱...... 一个爽朗的晴天&#xff0c;我听闻同事说有客户对他吐槽打板子价格太高&#xff0c;说着说着就开始吹起了牛逼...…

Spring MVC的核心类和注解——@RequestMapping注解(三)请求映射方式

一、请求映射方式的分类 基于注解风格的Spring MVC&#xff0c;通过RequestMapping注解指定请求映射的URL路径。URL路径映射常用的方式有基于请求方式的URL路径映射、基于Ant风格的URL路径映射和基于REST风格的URL路径映射。接下来分别对这三种请求映射方式进行详细讲解。 a. …

受风头痛的几种情况

受风是指人体外感风邪引起的疾病&#xff0c;不同的病因需要采用相应的治疗方法进行调理和治疗。风为六淫之一&#xff0c;具有轻扬开泄的特性&#xff0c;易伤人肌表&#xff0c;引起头痛等症状。 中医认为头疼受风是由于外感引起的&#xff0c;头疼可以分为外感和内伤两个原…

【TB作品】体重监控系统,ATMEGA16单片机,Proteus仿真

机电荷2018级课程设计题目及要求 题1:电子称重器设计 功能要求: 1)开机显示时间(小时、分)、时分可修改; 2)用滑动变阻器模拟称重传感器(测量范围0- 200g),数码管显示当前重量值,当重量值高于高 值时,红灯长亮; 3)当重量值低于低值时,黄灯长亮; 4)当重量值在正常值时,绿灯亮; 5…

代码随想录打卡第十五天

代码随想录–二叉树部分 day15 二叉树第三天 文章目录 代码随想录--二叉树部分一、力扣110--平衡二叉树二、力扣257--二叉树的所有路径三、力扣404--左叶子之和四、力扣222--完全二叉树的节点个数 一、力扣110–平衡二叉树 代码随想录题目链接&#xff1a;代码随想录 给定一个…

关于DB_CREATE_FILE_DEST初始化参数

DB_CREATE_FILE_DEST指定了OMF的默认位置。 OMF指 Oracle Managed Files&#xff0c;OMF指定一个文件系统中的目录&#xff0c;数据库会在此目录中自动创建、命名和管理数据库对象级别的文件。 OMF用的较多的是数据文件。 来看一个例子。已有一个PDB&#xff1a;orclpdb1&am…

springboot学生档案信息管理系统-计算机毕业设计源码96509

目 录 第 1 章 引 言 1.1 选题背景 1.2 研究现状 1.3 论文结构安排 第 2 章 系统的需求分析 2.1 系统可行性分析 2.1.1 技术方面可行性分析 2.1.2 经济方面可行性分析 2.1.3 法律方面可行性分析 2.1.4 操作方面可行性分析 2.2 系统功能需求分析 2.3 系统性需求分析…

GBase 8c V5 主备式部署手册

GBase 8c V5 主备式部署实操 一、前言二、环境准备三、安装四、数据库启停五、卸载六、连接和 SQL 测试 一、前言 GBase 8c 是 GBASE公司&#xff08;天津南大通用数据技术股份有限公司&#xff09;自主研发的一款多模多态的企业级分布式数据库&#xff1a;支持行存、列存、内存…

JAVA程序打包时报错,但是运行时正常。

报错&#xff1a;Could not transfer artifact com.alibaba:fastjson:pom:1.2.83 from/to clojars... 背景&#xff1a;需要将fastjson从1.2.70升级到1.2.83&#xff1b;并且编译环境是局域网不可以连接互联网&#xff1b;每个项目组都是独立的私有仓库。 操作&#xff1a;在本…

Failed to download metadata for repo ‘docker-ce-stable‘

这个问题是由于在安装 clamav 和 clamav-update 时&#xff0c;无法下载 Docker CE Stable 库的元数据&#xff0c;可能的原因是网络连接超时或访问该网址受限。以下是一些可能的解决办法&#xff1a; 检查网络连接&#xff1a; 确保服务器的网络连接正常&#xff0c;尤其是与互…

海外发稿: 秘鲁-区块链新闻媒体通稿宣发

秘鲁媒体单发 随着全球化的不断深入&#xff0c;海外发稿已经成为众多企业宣传推广的重要方式之一。而在海外发稿的选择中&#xff0c;秘鲁媒体的地位尤为重要。秘鲁作为南美洲的重要国家之一&#xff0c;拥有众多知名媒体平台&#xff0c;包括diariodelcusco、serperuano、el…

mysql8 导入导出工具类,支持windows 和linux

概述 1&#xff09;导入导出工具类 支持windows 和linux&#xff0c;详见第3部分 2&#xff09;导入、导出参数在 dbeaver 中应用&#xff0c;详见第4部分 整理原因: 1&#xff09;中文乱码 --default-character-setutf8 2&#xff09;BLOB 导出后&#xff0c;导入失败 --he…