【数据结构】树

ops/2024/10/21 14:31:47/
二叉排序树的实现

二叉排序树:左子节点小于父节点,右子节点大于父节点。

每一个节点在内存当中都是一个对象,通过类构建节点。(类是构建对象的模板)

手动构建: 

public class Test {public static void main(String[] args) {TreeNode node1 = new TreeNode(5);TreeNode node2 = new TreeNode(7);TreeNode node3 = new TreeNode(4);TreeNode node4 = new TreeNode(2);TreeNode node5 = new TreeNode(0);TreeNode node6 = new TreeNode(3);node1.setRightTreeNode(node2);node1.setLeftTreeNode(node3);node3.setLeftTreeNode(node4);node4.setLeftTreeNode(node5);node3.setRightTreeNode(node6);System.out.println(node1.toString());}
}
public class TreeNode {private int value;private TreeNode leftTreeNode;private TreeNode rightTreeNode;public TreeNode(int data) {this.value = data;}public int getValue() {return value;}public void setValue(int value) {this.value = value;}public TreeNode getLeftTreeNode() {return leftTreeNode;}public void setLeftTreeNode(TreeNode leftTreeNode) {this.leftTreeNode = leftTreeNode;}public TreeNode getRightTreeNode() {return rightTreeNode;}public void setRightTreeNode(TreeNode rightTreeNode) {this.rightTreeNode = rightTreeNode;}@Overridepublic String toString() {return "TreeNode [value=" + value + ", leftTreeNode=" + leftTreeNode + ", rightTreeNode=" + rightTreeNode + "]";}
}

自动构建:

public class Test {public static void main(String[] args) {BinaryTree binaryTree = new BinaryTree();binaryTree.insert(5);binaryTree.insert(7);binaryTree.insert(4);binaryTree.insert(2);binaryTree.insert(0);binaryTree.insert(3);System.out.println(binaryTree.root);}
}
public class BinaryTree {//定义一个头指针public TreeNode root;public void insert(int value) {//新建节点TreeNode newNode = new TreeNode(value);if (root == null) {root = newNode;return;}//定义一个指针来遍历整个树TreeNode currentNode = root;//定义一个指针指向currentNode的前一个节点,目的是为了方便插入TreeNode preNode;while (true) {preNode = currentNode;if (newNode.getValue() > currentNode.getValue()) {  //向右走currentNode = currentNode.getRightTreeNode();if (currentNode == null) {preNode.setRightTreeNode(newNode);return;}} else {  //向左走currentNode = currentNode.getLeftTreeNode();if (currentNode == null) {preNode.setLeftTreeNode(newNode);return;}}}}
}
public class TreeNode {private int value;private TreeNode leftTreeNode;private TreeNode rightTreeNode;public TreeNode(int data) {this.value = data;}public int getValue() {return value;}public void setValue(int value) {this.value = value;}public TreeNode getLeftTreeNode() {return leftTreeNode;}public void setLeftTreeNode(TreeNode leftTreeNode) {this.leftTreeNode = leftTreeNode;}public TreeNode getRightTreeNode() {return rightTreeNode;}public void setRightTreeNode(TreeNode rightTreeNode) {this.rightTreeNode = rightTreeNode;}@Overridepublic String toString() {return "TreeNode [value=" + value + ", leftTreeNode=" + leftTreeNode + ", rightTreeNode=" + rightTreeNode + "]";}
}
查询
深度优先遍历

中序遍历:023457

public void inOrder(TreeNode root) {if (root == null) {return;}inOrder(root.getLeftTreeNode());System.out.println(root.getValue());inOrder(root.getRightTreeNode());
}

先序遍历:542037

public void beforeOrder(TreeNode root) {if (root == null) {return;}System.out.println(root.getValue());beforeOrder(root.getLeftTreeNode());beforeOrder(root.getRightTreeNode());
}

后序遍历:032475

public void afterOrder(TreeNode root) {if (root == null) {return;}afterOrder(root.getLeftTreeNode());afterOrder(root.getRightTreeNode());System.out.println(root.getValue());
}
广度优先遍历

队列:先进先出

public void levelOrder() {//首先新建一个队列LinkedList<TreeNode> queue = new LinkedList<>();queue.add(root);  //将根节点放入while(!queue.isEmpty()) {//头节点出队列root = queue.pop();if(root.getLeftTreeNode() != null) {queue.add(root.getLeftTreeNode());}if(root.getRightTreeNode() != null) {queue.add(root.getRightTreeNode());}}
}
删除
删除叶子节点

① 找到要删除的节点target。

② 找到target的父节点parent(要考虑父节点是否存在)。

③ 确定要删除的target节点和parent节点的关系,是左子树还是右子树。

④ 根据第三步的情况进行删除。

删除只有一个节点的子树

① 找到要删除的节点target。

② 找到target的父节点parent(要考虑父节点是否存在)。

③ 确定要删除的target节点和parent节点的关系,是左子树还是右子树。

④ 确定target有的是左子树还是右子树。

⑤ 如果target有左子树

        target是parent的左子树:parent.left = target.left

        target是parent的右子树:parent.right = target.left

⑥ 如果target有右子树

        target是parent的左子树:parent.left = target.right

        target是parent的右子树:parent.right = target.right

删除有两个节点的子树

① 找到要删除的节点target。

② 找到target的父节点parent(要考虑父节点是否存在)。

③ 找到target右子树的最小值(或左子树的最大值)

④ 将右子树的最小值(或左子树的最大值)和target交换,然后删除右子树的最小值(或左子树的最大值)节点。

//找到要删除的节点public TreeNode search(TreeNode root, int value) {if (root == null) {return null;}if (value == root.getValue()) {return root;}else if(value < root.getValue()) {//判断左子树是否为空if (root.getLeftTreeNode() == null) {return null;}return search(root.getLeftTreeNode(), value);}else {//判断右子树是否为空if (root.getRightTreeNode() == null) {return null;}return search(root.getRightTreeNode(), value);}}//找到待删除的父节点public TreeNode searchParent(TreeNode root, int value) {if (root == null) {return null;}if ((root.getLeftTreeNode() != null && root.getLeftTreeNode().getValue() == value) || (root.getRightTreeNode() != null) && root.getRightTreeNode().getValue() == value)) {return root;}else {if (root.getLeftTreeNode() != null && value < root.getValue()) {return searchParent(root.getLeftTreeNode(), value);}else if (root.getRightTreeNode() != null && value >= root.getValue()) {return search(root.getRightTreeNode(), value);}else {return null;}}}//找到右子树的最小值public int rightTreeNodeMin(TreeNode node) {TreeNode currentNode = node;while (currentNode.getLeftTreeNode() != null) {currentNode = currentNode.getLeftTreeNode();}return currentNode.getValue();}

http://www.ppmy.cn/ops/10163.html

相关文章

消息队列选型(RabbitMq、RocketMq、Kafaka)

文章目录 前言RabbitMq优点缺点 RocketMq优点缺点 Kafaka优点缺点 总结 前言 当引入消息队列时&#xff0c;常见的选择包括ActiveMQ、Kafka、RabbitMQ和RocketMQ。然而&#xff0c;近年来&#xff0c;ActiveMQ的活跃度已经下降&#xff0c;很多公司已经不再使用这款消息队列中…

Golang | Leetcode Golang题解之第44题通配符匹配

题目&#xff1a; 题解&#xff1a; func isMatch(s string, p string) bool {for len(s) > 0 && len(p) > 0 && p[len(p)-1] ! * {if charMatch(s[len(s)-1], p[len(p)-1]) {s s[:len(s)-1]p p[:len(p)-1]} else {return false}}if len(p) 0 {retur…

《HCIP-openEuler实验指导手册》1.3Apache动态功能模块加载卸载练习

1.3.1 配置思路 mod_status 模块可以帮助管理员通过web界面监控Apache运行状态&#xff0c;通过LoadModule指令加载该模块&#xff0c;再配置相关权限&#xff0c;并开启ExtendedStatus后&#xff0c;即可使用该模块。 1.3.2 配置步骤 检查mod_status模块状态&#xff08;使…

模拟相机拍照——对文档进行数据增强

一. 背景 假如我们有一个标准文件&#xff0c;我们对其进行文字识别、版面分析或者其他下游任务就比较容易。然而&#xff0c;当图片是手机拍照获取的&#xff0c;图片中往往有阴影、摩尔纹、弯曲。 那么&#xff0c;如何通过标准的文档&#xff0c;获得类似相机拍照的图片呢&…

04-2.Vue2.x data与el的2种写法

文章目录 data与el的2种写法 data与el的2种写法 <!DOCTYPE html> <html lang"en"><head><!-- data与el的2种写法1. el有2种写法&#xff1a;1)new Vue时直接传递el属性----常用2)通过vm.$mount(#root)指定容器 ----不常用2.data有2种写法&…

设计模式(工厂方法-Factory Method)结构|原理|优缺点|场景|示例

目录 设计模式&#xff08;分类&#xff09; 设计模式&#xff08;六大原则&#xff09; 创建型 工厂方法 抽象工厂模式 单例模式 建造者模式 原型模式 结构型 适配器模式 装饰器模式 代理模式 设计模式中的工厂方法&…

Pytorch重点概念笔记:都是本人学习中真实遇到的(一)

1.torch.squeeze的原理参数和使用方法 torch.squeeze 是PyTorch中的一个函数,用于减少张量的维数,具体来说,它会移除所有维数为1的维度。这个操作通常用于处理那些在特定操作(如卷积或池化)后可能产生不必要的单维度张量。 原理: 在某些情况下,张量操作会生成形状中包…

什么是全局特征,什么又是局部特征

全局特征和局部特征是用来描述数据中信息的两种不同方式&#xff0c;特别是在图像处理、模式识别和机器学习领域中经常被提到。它们有助于理解和分析数据的不同层面&#xff1a; 全局特征&#xff08;Global Features&#xff09; 全局特征描述了整个数据集的整体属性。在图像…