二叉查找树 Java实现
定义:
一棵二叉查找树是一棵二叉树,每个节点都含有一个Comparable的键(以及对应的值)。
每个节点的键都大于左子树中任意节点的键而小于右子树中任意节点的键。
树的术语:
Name | Function |
---|---|
路径 | 顺着连接点的边从一个节点走向另一个节点,所经过的节点的顺序排列就称为路径。 |
根 | 树顶端的节点就称为根,一棵树只有一个根,如果要把一个节点和边的集合定义为树,那么从根到其他任何一个节点都必须有一条路径。 |
父节点 | 每个节点(除了根)都恰好有一条边向上连接到另一个节点,上面的节点就称为下面节点的“父节点”。 |
子节点 | 每个节点都可能有一条或多条边向下连接其他节点,下面的这些节点就称为它的“子节点”。 |
叶节点 | 没有子节点的节点称为“叶子节点”或简称“叶节点”。树只能有一个根,但是可以有很多叶节点。 |
子树 | 每个节点都可以作为子树的根,它和它所有的子节点,子节点的子节点等都含在子树中。 |
访问 | 当程序控制流程到达某个节点的时候,就称为“访问”这个节点,通常是为了在这个节点处执行某种操作,例如查看节点某个数据字段的值或者显示节点。 |
遍历 | 遍历树意味着要遵循某种特定的顺序访问树中的所有节点。 |
层 | 一个节点的层数是指从根开始到这个节点有多少“代”。 |
关键字 | 可以看到,对象中通常会有一个数据域被指定为关键字值。这个值通常用于查询或者其他操作。 |
二叉树 | 如果树中的每个节点最多只能有两个子节点,这样的树就称为“二叉树”。 |
性质:
- 若它的左子树不为空,则左子树上的所有节点的值都小于它的根节点的值;
- 若它的右子树不为空,则右子树上所有节点的值都大于它的根节点的值;
- 其他的左右子树也分别为二叉查找树;
- 二叉查找树是动态查找表,在查找的过程中可见添加和删除相应的元素,在这些操作中需要保持二叉查找树的以上性质。
根据其二叉树的特性,节点类如下:
public class Node {public int index;//关键字段public String data;//值public Node leftNode;//左节点public Node rightNode;//右节点@Overridepublic boolean equals(Object obj) {return EqualsBuilder.reflectionEquals(this, obj);}@Overridepublic int hashCode() {return HashCodeBuilder.reflectionHashCode(this);}
}
其中引用了commons-lang3包中的内容,作为对象进行比较
查找某个节点,相当于二分查找,如果小于当前节点,则走左边,如果大于当前节点,则走右边。当最后叶子节点还没有找到,则没有找到
public Node findNode(int key){Node current = root;while(current.index != key){if(key < current.index){//左节点current = current.leftNode;}else{//右节点current = current.rightNode;}if(current == null){return null;}}return current;
}
插入节点,按照插入的节点都不会出现重复关键字。每一次插入都将变为根节点的子节点,例如根节点关键字为1,接下来插入的节点则变为根节点的右子节点。
public void insertNode(int key,String value){Node node = new Node();node.index = key;node.data = value;if(root == null){root = node;return;}//找到插入节点的位置Node parent = root;Node current = root;while(true){parent = current;if(key == current.index){return;}if(key < current.index){//左节点current = current.leftNode;if(current == null){//当前节点已经是叶子结点了parent.leftNode = node; return;}}else{current = current.rightNode;if(current == null){parent.rightNode = node;return;}}}
}
遍历节点,中序遍历.
- 调用自身来遍历节点的左子树
- 访问这个节点
- 掉用自身来遍历节点的右子树
public void inOrder(Node localRoot) {if (localRoot != null) {inOrder(localRoot.leftNode);System.out.println("索引:" + localRoot.index + ",值:" + localRoot.data);inOrder(localRoot.rightNode);}
}
删除节点,分三种情况:
- 删除节点没有子节点,那么将父节点的左节点或者是右节点设置为空
- 删除节点只有一个子节点,删除该节点后,该节点的子节点变为父节点的子节点,如果删除节点时父节点的左节点,那么父节点的左节点指向该节点的子节点,反之则右节点指向删除节点的子节点。
- 删除节点有两个字节点,删除了该节点后,则需要选择一个后继节点,并且还不破坏该二叉树的特性(左节点要小于右节点),一般是从删除节点的右节点中找到一个后继节点,而这个节点是右子树的最小值。
public boolean delete(int key) {Node current = root;Node parent = root;boolean isLeftChild = true;//找到被删除的节点,并标识该节点是否为左节点while (current.index != key) {parent = current;if (key < current.index) {isLeftChild = true;current = current.leftNode;} else {isLeftChild = false;current = current.rightNode;}if (current == null) {return false;}}//第一种情况,删除节点为子节点if (current.leftNode == null && current.rightNode == null) {if (current == root) {root = null;} else {if (isLeftChild) {parent.leftNode = null;} else {parent.rightNode = null;}}} else if ((current.leftNode != null && current.rightNode == null) || (current.leftNode == null && current.rightNode != null)) {//第二中情况,删除节点只包含一个子节点,则将子节点移动动当前节点中if (current.rightNode == null) {//删除的节点的左节点有值,右节点为空if (root == current) {root = current.leftNode;} else {if (isLeftChild) {parent.leftNode = current.leftNode;} else {parent.rightNode = current.leftNode;}}} else {//删除的节点的右节点有值,左节点为空if (root == current) {root = current.rightNode;} else {if (isLeftChild) {parent.leftNode = current.rightNode;} else {parent.rightNode = current.rightNode;}}}} else if (current.leftNode != null && current.rightNode != null) {//第三种情况,删除节点中有左右两个节点//找到后继节点Node processer = processer(current);if (current == root) {//删除是根节点,则root = processer;} else {if (isLeftChild) {parent.leftNode = processer;} else {parent.rightNode = processer;}}//选中的节点的左节点与删除节点的左节点相连processer.leftNode = current.leftNode;}return true;}//找到后继节点private Node processer(Node delNode) {Node parent = delNode;Node success = delNode;Node current = delNode.rightNode;while (current != null) {// 后继节点父节点首先保存后继节点的状态parent = current;success = current;// 后继节点 不断的向左更新current = current.leftNode;}// 假如我们找到的后继节点不直接是 要删除节点的右节点 而是在其右节点那条子树上面最小的一个节点if (success != delNode.rightNode) {//后继节点的父节点断开其与后继节点左边的引用,重新连接上后继节点的右子节点(因为后继节点是没有左子节点的,锁以要保存之前树的状态,还要把后继节点的右子节点处理一下,不管 其存在不存在)parent.leftNode = success.rightNode;// 这时候后继节点的右边已经空了 上一条语句已经将其给了自己父节点的左子节点 然后让后继节点的右边 连接要删除节点的右子树success.rightNode = delNode.rightNode;}return success;}
转载于:https://www.cnblogs.com/skyice/p/10618303.html
二叉查找树 Java实现相关推荐
- 二叉查找树Java实现代码
二叉查找树(Binary Search Tree),或者是一颗空树,或者是具有下列性质的二叉树: 1.若它的左子树不空,则其左子树上的所有结点的值均小于它根结点的值: 2.若它的右子树不空,则其右子树 ...
- AVL树-自平衡二叉查找树(Java实现)
在计算机科学中,AVL树是最先发明的自平衡二叉查找树.AVL树得名于它的发明者 G.M. Adelson-Velsky 和 E.M. Landis,他们在 1962 年的论文 "An alg ...
- 二叉查找树--java
package com.test.tree;public class BinarySearchTree<T extends Comparable<? super T>> {/* ...
- 二叉查找树 java代码实现
文章目录 代码实现 节点实现类 二叉树实现 单元测试 代码实现 节点实现类 package csdn.dreamzuora.tree;/*** Title:* Description:** @vers ...
- 数据结构笔记--二叉查找树概述以及java代码实现
一些概念: 二叉查找树的重要性质:对于树中的每一个节点X,它的左子树任一节点的值均小于X,右子树上任意节点的值均大于X. 二叉查找树是java的TreeSet和TreeMap类实现的基础. 由于树的递 ...
- 数据结构与算法-二叉查找树(java描述)
一.概述 二叉排序树(Binary Sort Tree)又称二叉查找树(Binary Search Tree),亦称二叉搜索树. 1.1.定义 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: ...
- 二叉查找树的Java实现
转自:http://blog.csdn.net/lovesqcc/article/details/6246615 为了克服对树结构编程的恐惧感,决心自己实现一遍二叉查找树,以便掌握关于树结构编程的一些 ...
- xdocument查找节点值_二叉查找树(java)
一棵二叉查找树(BST)是一颗二叉树,其中每个节点都含有一个Comparable的键且每个节点的键(以及相关的值)都大于其左子树中的任意节点的键而小于右子树的任意结点的键. 数据表示 和链表一样,我们 ...
- 分治法在二叉树遍历中的应用(JAVA)--二叉查找树高度、前序遍历、中序遍历、后序遍
分治法在二叉树遍历中的应用 二叉树本身就是由两个更小的部分组成--左子树和右子树,所以二叉树的问题非常适合用分治法来解决. 二叉树的高度:从叶子到根之间的最长路径.我们可以理解为根的左子树高度和右子树 ...
最新文章
- FusionNet:基于稀疏雷达点云和RGB图像的深度图补全
- pythonoracle数据库操作_Python学习笔记4(操作oracle数据库)
- 实现strstr库函数功能
- 五中高考2021成绩查询,全市2021届高三第二次模拟考试成绩分析会在开封五中胜利召开...
- CentOs6.5下安装svn
- 12分钟即达背后的智能支撑
- 牛津词典 2018 年度词汇 ——「有毒」!
- 编程之美 裴波那楔数列
- 暴风转码转超清文件_暴风影音16破解版下载-暴风影音16多开精简版(附怎么用) v9.4.1029.1111...
- 用靠谱助手多开玩梦幻西游手游
- CentOS 7 systemd添加自定义系统服务
- Cobal Strike的学习与使用
- JAVA基础(43)彻底理解cookie、session、token
- 更换固态硬盘和机械硬盘以及重装系统
- csgo社区自建服务器,CSGO官方社区服黄页测试版上线
- 《JOEL说软件》中文版翻译质量令人失望
- CAD 查找指定部件数量
- 跳板机/堡垒机并不安全
- 电影与幸福感期末答案和平时测试答案
- 要你干掉机器人,而不是逼死强迫症
热门文章
- 业界 | 李彦宏:中国人愿意用隐私交换便利性;无人车事故是“人咬狗”新闻...
- 影响SDN和NFV部署速度的两个因素
- Oracle 9i/10g/11g数据库升级路线图总览
- (最小生成树) Networking -- POJ -- 1287
- 对于fmri的设计矩阵构造的一个很直观的解释-by 西南大学xulei教授
- 计算器软件----表达式求值
- 如何解决局域网内传输速度过慢问题
- 一寸、两寸证件照photoshop批处理动作
- 过冰点自定义日期时间
- Python 进阶之路 (十二) 尾声即是开始