java 二叉排序_java实现二叉排序树
最近终于静下心来,自己实现了个二叉排序树,还是很有成就感的。
package tree;
public class TreeNode {
//结点存放的数据
public T data;
//当前结点的父结点
public TreeNode parent;
//当前结点的左孩子
public TreeNode leftChild;
//当前结点的右孩子
public TreeNode rightChild;
public TreeNode(T data,TreeNode parent)
{
this.data = data;
this.leftChild = null;
this.rightChild = null;
this.parent = parent;
}
}
package tree;
/**
* 二叉排序树或者是一棵空树, 或者是一棵具有如下性质的二叉树
* (1)、若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
* (2)、若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
* (3)、左、右子树也分别为二叉排序树;
*/
//二叉排序树的结构通常不是一次生成的,而是在查找过程中动态构建的;
public class BinarySortTree>
{
//根结点指针
public TreeNode rootNode = null;
//二叉树的结点个数
public int nodeCount = 0;
//获取targetData在二叉排序树中对应的结点指针
public TreeNode find(T targetData)
{
TreeNode curNode = this.rootNode;
while (curNode != null)
{
T curNodeData = curNode.data;
if(curNodeData.compareTo(targetData) == 0)
{
return curNode;
}
else if(curNodeData.compareTo(targetData) > 0)
{
curNode = curNode.leftChild;
}
else
{
curNode = curNode.rightChild;
}
}
return null;
}
public TreeNode add(T targetData)
{
TreeNode targetNode= find(targetData);
//已经存在,不用再插入新结点
if(targetNode != null)
{
return targetNode;
}
//没有根结点,需要创建一个根结点,存放数据targetData
if(this.rootNode == null)
{
this.rootNode = new TreeNode(targetData, null);
this.nodeCount = 1;
return this.rootNode;
}
//已经存在根节点的情况,但是没有对应targetData的结点
TreeNode insertPos = findInsertPos(targetData);
TreeNode tempNode = new TreeNode(targetData, insertPos);
this.nodeCount++;
if(targetData.compareTo(insertPos.data) > 0 )
{
insertPos.rightChild = tempNode;
}
else
{
insertPos.leftChild = tempNode;
}
return tempNode;
}
public void delete(T targetData)
{
TreeNode tagNode = find(targetData);
//不存在,直接返回
if( tagNode == null)
{
return;
}
//要删除的结点是叶子结点
if(tagNode.leftChild == null && tagNode.rightChild == null)
{
deleteWhenLeaf(tagNode);
}
//要删除的结点只有左子树,或只有右子树
else if(tagNode.leftChild == null || tagNode.rightChild == null)
{
deleteWhenSingleChild(tagNode);
}
else
{
deleteWhenTwoChild(tagNode);
}
}
//删去叶子结点不破坏整棵树的结构,只需修改其父结点的孩子指针
private void deleteWhenLeaf(TreeNode tagNode)
{
this.nodeCount--;
TreeNode parent = tagNode.parent;
//要删除的是根结点
if(parent == null)
{
this.rootNode = null;
}
else
{
if(parent.leftChild == tagNode)
{
parent.leftChild = null;
}
else
{
parent.rightChild = null;
}
}
}
//若p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点f的左子树(当*p是左子树)
//或右子树(当*p是右子树)即可
private void deleteWhenSingleChild(TreeNode tagNode)
{
this.nodeCount--;
//当前结点的父亲
TreeNode parent = tagNode.parent;
//当前结点的左孩子
TreeNode left = tagNode.leftChild;
//当前结点的右孩子
TreeNode right = tagNode.rightChild;
if(left != null)
{
left.parent = parent;
}
else
{
right.parent = parent;
}
//要删除的是根结点
if(parent == null)
{
if(left != null)
{
this.rootNode = left;
}
else
{
this.rootNode = right;
}
}
else//删除的结点不是根结点
{
if(left != null)
{
parent.leftChild = left;
}
else
{
parent.rightChild = right;
}
}
}
//tagNode结点的后继结点肯定无左子树;前驱结点肯定没有右子树;
//由于tagNode既有左孩子,又有右孩子,所以前驱和后继都不可能是null
//假如tagNode的前驱是before,则用before代替tagNode位置;
//before的左子树代替before的位置
private void deleteWhenTwoChild(TreeNode tagetNode)
{
this.nodeCount--;
//tagetNode的前驱结点是before
TreeNode before = searchPredecessor(tagetNode);
//1.before的左子树取代结点before的位置
if(before.parent.leftChild == before)
{
before.parent.leftChild = before.leftChild;
}
else
{
before.parent.rightChild = before.leftChild;
}
if(before.leftChild != null)
{
before.leftChild.parent = before.parent;
}
//2.before取代tagetNode的位置
before.parent = tagetNode.parent;
before.leftChild = tagetNode.leftChild;
before.rightChild = tagetNode.rightChild;
//3.改变tagetNode的父结点的孩子指针
if(tagetNode.parent == null)
{
this.rootNode = before;
}
else
{
if(tagetNode.parent.leftChild == tagetNode)
{
tagetNode.parent.leftChild = before;
}
else
{
tagetNode.parent.rightChild = before;
}
}
}
//获取targetData在二叉排序中插入位置
//如果targetData在二叉树中已经存在,则不需要再插入,返回null
public TreeNode findInsertPos(T targetData)
{
//将要插入的位置
TreeNode willInsert = null;
TreeNode curNode = this.rootNode;
while (curNode != null)
{
T curNodeData = curNode.data;
//结点已经存在,插入位置设为null
if(curNodeData.compareTo(targetData) == 0)
{
willInsert = null;
break;
}
else if(curNodeData.compareTo(targetData) >0)
{
willInsert = curNode;
curNode = curNode.leftChild;
}
else
{
willInsert = curNode;
curNode = curNode.rightChild;
}
}
return willInsert;
}
//二叉排序树的中序遍历,查找tagetNode结点的后继结点
//如果没有后继结点,则返回null;
public TreeNode searchSuccessor(TreeNode tagetNode)
{
if(tagetNode == null)
{
return null;
}
//从右子树中寻找后继结点
if(tagetNode.rightChild != null)
{
return searchMinValueNode(tagetNode.rightChild);
}
//从父节点向上寻找后继
else
{
//根结点没有右子树,就没有后继结点
if(tagetNode.parent == null)
{
return null;
}
else
{
TreeNode temp = tagetNode;
while (temp.parent != null)
{
if(temp.parent.leftChild == temp)
{
break;
}
temp = temp.parent;
}
return temp.parent;
}
}
}
//查找某个结点的前驱,如果没有前驱结点,则返回null
public TreeNode searchPredecessor(TreeNode tagetNode)
{
if(tagetNode == null)
{
return null;
}
if(tagetNode.leftChild != null)
{
return searchMaxValueNode(tagetNode.leftChild);
}
else
{
//根结点没有左子树,就没有前驱结点
if(tagetNode.parent == null)
{
return null;
}
else
{
TreeNode temp = tagetNode;
while (temp.parent != null)
{
if(temp.parent.rightChild == temp)
{
break;
}
temp = temp.parent;
}
return temp.parent;
}
}
}
//查找以root为根结点的二叉排序树中,最小的数据值对应的结点
public TreeNode searchMinValueNode(TreeNode root)
{
if(root == null)
{
return null;
}
TreeNode resultNode = root;
while (resultNode.leftChild != null)
{
resultNode = resultNode.leftChild;
}
return resultNode;
}
//查找以root为根结点的二叉排序树中,最大的数据值对应的结点
public TreeNode searchMaxValueNode(TreeNode root)
{
if(root == null)
{
return null;
}
TreeNode resultNode = root;
while (resultNode.rightChild != null)
{
resultNode = resultNode.rightChild;
}
return resultNode;
}
public void inorderTraversal(TreeNode node)
{
if(node == null)
{
return;
}
inorderTraversal(node.leftChild);
System.out.println(node.data);
inorderTraversal(node.rightChild);
}
}
java 二叉排序_java实现二叉排序树相关推荐
- 二叉排序树查找的c语言程序,C语言二叉排序(搜索)树实例
本文实例为大家分享了C语言二叉排序(搜索)树实例代码,供大家参考,具体内容如下 /**1.实现了递归 非递归插入(创建)二叉排序(搜索)树: 分别对应Insert_BinSNode(TBinSNode ...
- 掉一根头发,搞定二叉排序(搜索)树
文章已收录在 数据结构与算法学习仓库 前言 前面介绍学习的大多是线性表相关的内容,把指针搞懂后其实也没有什么难度,规则相对是简单的,后面会讲解一些比较常见的数据结构,用多图的方式让大家更容易吸收. 在 ...
- 数据结构与算法—二叉排序(查找)树
目录 前言 树 二叉树 二叉排序(搜索)树 概念 构造 主要方法 findmax(),findmin() isContains(int x) insert(int x) delete(int x) 完 ...
- java二叉查找算法_Java手写二叉搜索树算法
package com.zyizou.basis.demo.tree; /** * 手写二叉搜索树的逻辑 * * @author zibin */ public class BinarySearchT ...
- C语言——查找(折半、分块、二叉排序、哈希法)
前言 本篇主要介绍查找概念及各类查找方法. 看完本篇,你将了解到: 1.查找问题概述(查找表可进行的操作.时间开销.一些计算方法) 2.顺序表的查找(存储方式.算法时间性能) 3.折半查找(可递归可迭 ...
- java 二叉堆_二叉堆(三)之 Java的实现
概要 前面分别通过C和C++实现了二叉堆,本章给出二叉堆的Java版本.还是那句话,它们的原理一样,择其一了解即可. 二叉堆的介绍 二叉堆是完全二元树或者是近似完全二元树,按照数据的排列方式可以分为两 ...
- [剑指offer]面试题第[68-2]题[Leetcode][第236题][JAVA][二叉搜索树的最近公共祖先][递归]
[问题描述][中等] 235/68-1 搜索二叉树 236/68-2 二叉树 [解答思路] 递归 时间复杂度:O(N) 空间复杂度:O(N) 情况 1. , 2. , 3. , 4. 的展开写法如下. ...
- java二次排序_使用java 实现二次排序
二次排序工具类: import java.io.Serializable; import scala.math.Ordered; /** * @author 作者 E-mail: * @version ...
- Java二叉搜索树转循环链表,关于java:二叉搜索树转换为单向链表interview1712
题目形容 二叉树数据结构TreeNode可用来示意单向链表(其中left置空,right为下一个链表节点).实现一个办法,把二叉搜寻树转换为单向链表,要求仍然合乎二叉搜寻树的性质,转换操作应是旧址的, ...
最新文章
- R语言ggplot2可视化:ggplot2可视化水平堆叠条形图、并且在每个堆叠条形图的内部居中添加百分比文本标签信息
- String构造方法和字符集编码转换
- SQL server与Oracle触发器的创建与使用
- 【自动化测试】Python 读取 .ini 格式文件
- ABAP中怎样获取随机数
- mongodb服务部署
- PHP从零开始--数据库
- 关于C语言野指针的问题
- 将一个16进制数转化为10进制数
- java对mysql的简单操作——增加数据
- 常见RPM,YUM,DNF指令
- python tornado 工程范例
- 网站后台发通知页面效果图
- SQL语句中AND OR运算符优先级
- Mac工具PullTube如何在下载列表中创建重复项
- ip纯真数据库查询国家省市名称
- 实训4——RFID刷卡开锁
- python27是什么文件夹可以删除吗_python如何跳过错误继续运行,同时删除产生错误的文档...
- css 里面写响应式布局,CSS3怎么做出响应式布局
- 塞班s60v3手电筒sisx_塞班s60v3闪光灯手电筒软件可以发给我吗?谢谢!